From 0be1f7e31b14364f82dfdb5cd6c072479c176866 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Apr 2024 12:37:44 +0000 Subject: [PATCH 1/2] chore(deps): Bump doctrine/dbal from 3.7.0 to 3.8.3 Bumps [doctrine/dbal](https://github.com/doctrine/dbal) from 3.7.0 to 3.8.3. - [Release notes](https://github.com/doctrine/dbal/releases) - [Commits](https://github.com/doctrine/dbal/compare/3.7.0...3.8.3) --- updated-dependencies: - dependency-name: doctrine/dbal dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- composer.lock | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/composer.lock b/composer.lock index e6859ab7c..13e206f24 100644 --- a/composer.lock +++ b/composer.lock @@ -570,16 +570,16 @@ }, { "name": "doctrine/dbal", - "version": "3.7.0", + "version": "3.8.3", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "00d03067f07482f025d41ab55e4ba0db5eca2cdf" + "reference": "db922ba9436b7b18a23d1653a0b41ff2369ca41c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/00d03067f07482f025d41ab55e4ba0db5eca2cdf", - "reference": "00d03067f07482f025d41ab55e4ba0db5eca2cdf", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/db922ba9436b7b18a23d1653a0b41ff2369ca41c", + "reference": "db922ba9436b7b18a23d1653a0b41ff2369ca41c", "shasum": "" }, "require": { @@ -595,14 +595,14 @@ "doctrine/coding-standard": "12.0.0", "fig/log-test": "^1", "jetbrains/phpstorm-stubs": "2023.1", - "phpstan/phpstan": "1.10.35", + "phpstan/phpstan": "1.10.58", "phpstan/phpstan-strict-rules": "^1.5", - "phpunit/phpunit": "9.6.13", + "phpunit/phpunit": "9.6.16", "psalm/plugin-phpunit": "0.18.4", "slevomat/coding-standard": "8.13.1", - "squizlabs/php_codesniffer": "3.7.2", - "symfony/cache": "^5.4|^6.0", - "symfony/console": "^4.4|^5.4|^6.0", + "squizlabs/php_codesniffer": "3.9.0", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/console": "^4.4|^5.4|^6.0|^7.0", "vimeo/psalm": "4.30.0" }, "suggest": { @@ -663,7 +663,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.7.0" + "source": "https://github.com/doctrine/dbal/tree/3.8.3" }, "funding": [ { @@ -679,20 +679,20 @@ "type": "tidelift" } ], - "time": "2023-09-26T20:56:55+00:00" + "time": "2024-03-03T15:55:06+00:00" }, { "name": "doctrine/deprecations", - "version": "1.1.2", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931" + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/4f2d4f2836e7ec4e7a8625e75c6aa916004db931", - "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", "shasum": "" }, "require": { @@ -724,9 +724,9 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.2" + "source": "https://github.com/doctrine/deprecations/tree/1.1.3" }, - "time": "2023-09-27T20:04:15+00:00" + "time": "2024-01-30T19:34:25+00:00" }, { "name": "doctrine/event-manager", From 3e046bdefbd7f237cfed8beb54d7cdd400e23d57 Mon Sep 17 00:00:00 2001 From: nextcloud-command Date: Fri, 5 Apr 2024 12:39:31 +0000 Subject: [PATCH 2/2] chore(autoloader): Dump autoloader Signed-off-by: nextcloud-command --- composer/autoload_classmap.php | 9 + composer/autoload_static.php | 9 + composer/installed.json | 38 ++-- composer/installed.php | 16 +- doctrine/dbal/src/Connection.php | 11 +- .../PrimaryReadReplicaConnection.php | 4 +- .../dbal/src/Driver/AbstractMySQLDriver.php | 5 + doctrine/dbal/src/Driver/OCI8/Driver.php | 13 +- .../OCI8/Exception/InvalidConfiguration.php | 20 ++ doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php | 4 + doctrine/dbal/src/Driver/PgSQL/Driver.php | 1 + doctrine/dbal/src/Id/TableGenerator.php | 13 +- .../src/Platforms/AbstractMySQLPlatform.php | 36 ++- .../dbal/src/Platforms/AbstractPlatform.php | 118 +++++++--- doctrine/dbal/src/Platforms/DB2Platform.php | 17 +- .../src/Platforms/MariaDb1043Platform.php | 52 +++-- .../src/Platforms/MariaDb1060Platform.php | 16 ++ .../dbal/src/Platforms/MySQL80Platform.php | 6 + .../dbal/src/Platforms/OraclePlatform.php | 4 +- .../src/Platforms/PostgreSQL100Platform.php | 6 + .../dbal/src/Platforms/PostgreSQLPlatform.php | 11 +- .../SQL/Builder/SQLServerSelectSQLBuilder.php | 86 ++++++++ .../dbal/src/Platforms/SQLServerPlatform.php | 9 + .../dbal/src/Platforms/SqlitePlatform.php | 63 +++++- .../Query/Expression/CompositeExpression.php | 1 + doctrine/dbal/src/Query/ForUpdate.php | 21 ++ .../ForUpdate/ConflictResolutionMode.php | 27 +++ doctrine/dbal/src/Query/Limit.php | 30 +++ doctrine/dbal/src/Query/QueryBuilder.php | 207 ++++++++++++++---- doctrine/dbal/src/Query/SelectQuery.php | 107 +++++++++ .../SQL/Builder/DefaultSelectSQLBuilder.php | 95 ++++++++ .../dbal/src/SQL/Builder/SelectSQLBuilder.php | 12 + doctrine/dbal/src/Schema/Column.php | 4 +- .../dbal/src/Schema/MySQLSchemaManager.php | 15 +- .../src/Schema/SQLServerSchemaManager.php | 10 +- 35 files changed, 942 insertions(+), 154 deletions(-) create mode 100644 doctrine/dbal/src/Driver/OCI8/Exception/InvalidConfiguration.php create mode 100644 doctrine/dbal/src/Platforms/MariaDb1060Platform.php create mode 100644 doctrine/dbal/src/Platforms/SQLServer/SQL/Builder/SQLServerSelectSQLBuilder.php create mode 100644 doctrine/dbal/src/Query/ForUpdate.php create mode 100644 doctrine/dbal/src/Query/ForUpdate/ConflictResolutionMode.php create mode 100644 doctrine/dbal/src/Query/Limit.php create mode 100644 doctrine/dbal/src/Query/SelectQuery.php create mode 100644 doctrine/dbal/src/SQL/Builder/DefaultSelectSQLBuilder.php create mode 100644 doctrine/dbal/src/SQL/Builder/SelectSQLBuilder.php diff --git a/composer/autoload_classmap.php b/composer/autoload_classmap.php index 40c64c978..19834d353 100644 --- a/composer/autoload_classmap.php +++ b/composer/autoload_classmap.php @@ -1130,6 +1130,7 @@ 'Doctrine\\DBAL\\Driver\\OCI8\\Driver' => $vendorDir . '/doctrine/dbal/src/Driver/OCI8/Driver.php', 'Doctrine\\DBAL\\Driver\\OCI8\\Exception\\ConnectionFailed' => $vendorDir . '/doctrine/dbal/src/Driver/OCI8/Exception/ConnectionFailed.php', 'Doctrine\\DBAL\\Driver\\OCI8\\Exception\\Error' => $vendorDir . '/doctrine/dbal/src/Driver/OCI8/Exception/Error.php', + 'Doctrine\\DBAL\\Driver\\OCI8\\Exception\\InvalidConfiguration' => $vendorDir . '/doctrine/dbal/src/Driver/OCI8/Exception/InvalidConfiguration.php', 'Doctrine\\DBAL\\Driver\\OCI8\\Exception\\NonTerminatedStringLiteral' => $vendorDir . '/doctrine/dbal/src/Driver/OCI8/Exception/NonTerminatedStringLiteral.php', 'Doctrine\\DBAL\\Driver\\OCI8\\Exception\\SequenceDoesNotExist' => $vendorDir . '/doctrine/dbal/src/Driver/OCI8/Exception/SequenceDoesNotExist.php', 'Doctrine\\DBAL\\Driver\\OCI8\\Exception\\UnknownParameterIndex' => $vendorDir . '/doctrine/dbal/src/Driver/OCI8/Exception/UnknownParameterIndex.php', @@ -1255,6 +1256,7 @@ 'Doctrine\\DBAL\\Platforms\\MariaDb1027Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/MariaDb1027Platform.php', 'Doctrine\\DBAL\\Platforms\\MariaDb1043Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/MariaDb1043Platform.php', 'Doctrine\\DBAL\\Platforms\\MariaDb1052Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/MariaDb1052Platform.php', + 'Doctrine\\DBAL\\Platforms\\MariaDb1060Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/MariaDb1060Platform.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', @@ -1269,6 +1271,7 @@ '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\\SQLServer\\SQL\\Builder\\SQLServerSelectSQLBuilder' => $vendorDir . '/doctrine/dbal/src/Platforms/SQLServer/SQL/Builder/SQLServerSelectSQLBuilder.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', @@ -1282,11 +1285,17 @@ 'Doctrine\\DBAL\\Query' => $vendorDir . '/doctrine/dbal/src/Query.php', 'Doctrine\\DBAL\\Query\\Expression\\CompositeExpression' => $vendorDir . '/doctrine/dbal/src/Query/Expression/CompositeExpression.php', 'Doctrine\\DBAL\\Query\\Expression\\ExpressionBuilder' => $vendorDir . '/doctrine/dbal/src/Query/Expression/ExpressionBuilder.php', + 'Doctrine\\DBAL\\Query\\ForUpdate' => $vendorDir . '/doctrine/dbal/src/Query/ForUpdate.php', + 'Doctrine\\DBAL\\Query\\ForUpdate\\ConflictResolutionMode' => $vendorDir . '/doctrine/dbal/src/Query/ForUpdate/ConflictResolutionMode.php', + 'Doctrine\\DBAL\\Query\\Limit' => $vendorDir . '/doctrine/dbal/src/Query/Limit.php', 'Doctrine\\DBAL\\Query\\QueryBuilder' => $vendorDir . '/doctrine/dbal/src/Query/QueryBuilder.php', 'Doctrine\\DBAL\\Query\\QueryException' => $vendorDir . '/doctrine/dbal/src/Query/QueryException.php', + 'Doctrine\\DBAL\\Query\\SelectQuery' => $vendorDir . '/doctrine/dbal/src/Query/SelectQuery.php', 'Doctrine\\DBAL\\Result' => $vendorDir . '/doctrine/dbal/src/Result.php', 'Doctrine\\DBAL\\SQL\\Builder\\CreateSchemaObjectsSQLBuilder' => $vendorDir . '/doctrine/dbal/src/SQL/Builder/CreateSchemaObjectsSQLBuilder.php', + 'Doctrine\\DBAL\\SQL\\Builder\\DefaultSelectSQLBuilder' => $vendorDir . '/doctrine/dbal/src/SQL/Builder/DefaultSelectSQLBuilder.php', 'Doctrine\\DBAL\\SQL\\Builder\\DropSchemaObjectsSQLBuilder' => $vendorDir . '/doctrine/dbal/src/SQL/Builder/DropSchemaObjectsSQLBuilder.php', + 'Doctrine\\DBAL\\SQL\\Builder\\SelectSQLBuilder' => $vendorDir . '/doctrine/dbal/src/SQL/Builder/SelectSQLBuilder.php', 'Doctrine\\DBAL\\SQL\\Parser' => $vendorDir . '/doctrine/dbal/src/SQL/Parser.php', 'Doctrine\\DBAL\\SQL\\Parser\\Exception' => $vendorDir . '/doctrine/dbal/src/SQL/Parser/Exception.php', 'Doctrine\\DBAL\\SQL\\Parser\\Exception\\RegularExpressionError' => $vendorDir . '/doctrine/dbal/src/SQL/Parser/Exception/RegularExpressionError.php', diff --git a/composer/autoload_static.php b/composer/autoload_static.php index 46b1686be..1dc699d53 100644 --- a/composer/autoload_static.php +++ b/composer/autoload_static.php @@ -1787,6 +1787,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'Doctrine\\DBAL\\Driver\\OCI8\\Driver' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/OCI8/Driver.php', 'Doctrine\\DBAL\\Driver\\OCI8\\Exception\\ConnectionFailed' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/OCI8/Exception/ConnectionFailed.php', 'Doctrine\\DBAL\\Driver\\OCI8\\Exception\\Error' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/OCI8/Exception/Error.php', + 'Doctrine\\DBAL\\Driver\\OCI8\\Exception\\InvalidConfiguration' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/OCI8/Exception/InvalidConfiguration.php', 'Doctrine\\DBAL\\Driver\\OCI8\\Exception\\NonTerminatedStringLiteral' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/OCI8/Exception/NonTerminatedStringLiteral.php', 'Doctrine\\DBAL\\Driver\\OCI8\\Exception\\SequenceDoesNotExist' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/OCI8/Exception/SequenceDoesNotExist.php', 'Doctrine\\DBAL\\Driver\\OCI8\\Exception\\UnknownParameterIndex' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/OCI8/Exception/UnknownParameterIndex.php', @@ -1912,6 +1913,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'Doctrine\\DBAL\\Platforms\\MariaDb1027Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MariaDb1027Platform.php', 'Doctrine\\DBAL\\Platforms\\MariaDb1043Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MariaDb1043Platform.php', 'Doctrine\\DBAL\\Platforms\\MariaDb1052Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MariaDb1052Platform.php', + 'Doctrine\\DBAL\\Platforms\\MariaDb1060Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MariaDb1060Platform.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', @@ -1926,6 +1928,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 '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\\SQLServer\\SQL\\Builder\\SQLServerSelectSQLBuilder' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/SQLServer/SQL/Builder/SQLServerSelectSQLBuilder.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', @@ -1939,11 +1942,17 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'Doctrine\\DBAL\\Query' => __DIR__ . '/..' . '/doctrine/dbal/src/Query.php', 'Doctrine\\DBAL\\Query\\Expression\\CompositeExpression' => __DIR__ . '/..' . '/doctrine/dbal/src/Query/Expression/CompositeExpression.php', 'Doctrine\\DBAL\\Query\\Expression\\ExpressionBuilder' => __DIR__ . '/..' . '/doctrine/dbal/src/Query/Expression/ExpressionBuilder.php', + 'Doctrine\\DBAL\\Query\\ForUpdate' => __DIR__ . '/..' . '/doctrine/dbal/src/Query/ForUpdate.php', + 'Doctrine\\DBAL\\Query\\ForUpdate\\ConflictResolutionMode' => __DIR__ . '/..' . '/doctrine/dbal/src/Query/ForUpdate/ConflictResolutionMode.php', + 'Doctrine\\DBAL\\Query\\Limit' => __DIR__ . '/..' . '/doctrine/dbal/src/Query/Limit.php', 'Doctrine\\DBAL\\Query\\QueryBuilder' => __DIR__ . '/..' . '/doctrine/dbal/src/Query/QueryBuilder.php', 'Doctrine\\DBAL\\Query\\QueryException' => __DIR__ . '/..' . '/doctrine/dbal/src/Query/QueryException.php', + 'Doctrine\\DBAL\\Query\\SelectQuery' => __DIR__ . '/..' . '/doctrine/dbal/src/Query/SelectQuery.php', 'Doctrine\\DBAL\\Result' => __DIR__ . '/..' . '/doctrine/dbal/src/Result.php', 'Doctrine\\DBAL\\SQL\\Builder\\CreateSchemaObjectsSQLBuilder' => __DIR__ . '/..' . '/doctrine/dbal/src/SQL/Builder/CreateSchemaObjectsSQLBuilder.php', + 'Doctrine\\DBAL\\SQL\\Builder\\DefaultSelectSQLBuilder' => __DIR__ . '/..' . '/doctrine/dbal/src/SQL/Builder/DefaultSelectSQLBuilder.php', 'Doctrine\\DBAL\\SQL\\Builder\\DropSchemaObjectsSQLBuilder' => __DIR__ . '/..' . '/doctrine/dbal/src/SQL/Builder/DropSchemaObjectsSQLBuilder.php', + 'Doctrine\\DBAL\\SQL\\Builder\\SelectSQLBuilder' => __DIR__ . '/..' . '/doctrine/dbal/src/SQL/Builder/SelectSQLBuilder.php', 'Doctrine\\DBAL\\SQL\\Parser' => __DIR__ . '/..' . '/doctrine/dbal/src/SQL/Parser.php', 'Doctrine\\DBAL\\SQL\\Parser\\Exception' => __DIR__ . '/..' . '/doctrine/dbal/src/SQL/Parser/Exception.php', 'Doctrine\\DBAL\\SQL\\Parser\\Exception\\RegularExpressionError' => __DIR__ . '/..' . '/doctrine/dbal/src/SQL/Parser/Exception/RegularExpressionError.php', diff --git a/composer/installed.json b/composer/installed.json index 9823e6294..34231e2a5 100644 --- a/composer/installed.json +++ b/composer/installed.json @@ -591,17 +591,17 @@ }, { "name": "doctrine/dbal", - "version": "3.7.0", - "version_normalized": "3.7.0.0", + "version": "3.8.3", + "version_normalized": "3.8.3.0", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "00d03067f07482f025d41ab55e4ba0db5eca2cdf" + "reference": "db922ba9436b7b18a23d1653a0b41ff2369ca41c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/00d03067f07482f025d41ab55e4ba0db5eca2cdf", - "reference": "00d03067f07482f025d41ab55e4ba0db5eca2cdf", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/db922ba9436b7b18a23d1653a0b41ff2369ca41c", + "reference": "db922ba9436b7b18a23d1653a0b41ff2369ca41c", "shasum": "" }, "require": { @@ -617,20 +617,20 @@ "doctrine/coding-standard": "12.0.0", "fig/log-test": "^1", "jetbrains/phpstorm-stubs": "2023.1", - "phpstan/phpstan": "1.10.35", + "phpstan/phpstan": "1.10.58", "phpstan/phpstan-strict-rules": "^1.5", - "phpunit/phpunit": "9.6.13", + "phpunit/phpunit": "9.6.16", "psalm/plugin-phpunit": "0.18.4", "slevomat/coding-standard": "8.13.1", - "squizlabs/php_codesniffer": "3.7.2", - "symfony/cache": "^5.4|^6.0", - "symfony/console": "^4.4|^5.4|^6.0", + "squizlabs/php_codesniffer": "3.9.0", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/console": "^4.4|^5.4|^6.0|^7.0", "vimeo/psalm": "4.30.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." }, - "time": "2023-09-26T20:56:55+00:00", + "time": "2024-03-03T15:55:06+00:00", "bin": [ "bin/doctrine-dbal" ], @@ -687,7 +687,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.7.0" + "source": "https://github.com/doctrine/dbal/tree/3.8.3" }, "funding": [ { @@ -707,17 +707,17 @@ }, { "name": "doctrine/deprecations", - "version": "1.1.2", - "version_normalized": "1.1.2.0", + "version": "1.1.3", + "version_normalized": "1.1.3.0", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931" + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/4f2d4f2836e7ec4e7a8625e75c6aa916004db931", - "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", "shasum": "" }, "require": { @@ -735,7 +735,7 @@ "suggest": { "psr/log": "Allows logging deprecations via PSR-3 logger implementation" }, - "time": "2023-09-27T20:04:15+00:00", + "time": "2024-01-30T19:34:25+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -751,7 +751,7 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.2" + "source": "https://github.com/doctrine/deprecations/tree/1.1.3" }, "install-path": "../doctrine/deprecations" }, diff --git a/composer/installed.php b/composer/installed.php index a53a828bd..7de0318a0 100644 --- a/composer/installed.php +++ b/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'nextcloud/3rdparty', 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => '1d2219713ab10d22f2784178009c4d08b97a831e', + 'reference' => '0be1f7e31b14364f82dfdb5cd6c072479c176866', 'type' => 'library', 'install_path' => __DIR__ . '/../', 'aliases' => array(), @@ -92,18 +92,18 @@ 'dev_requirement' => false, ), 'doctrine/dbal' => array( - 'pretty_version' => '3.7.0', - 'version' => '3.7.0.0', - 'reference' => '00d03067f07482f025d41ab55e4ba0db5eca2cdf', + 'pretty_version' => '3.8.3', + 'version' => '3.8.3.0', + 'reference' => 'db922ba9436b7b18a23d1653a0b41ff2369ca41c', 'type' => 'library', 'install_path' => __DIR__ . '/../doctrine/dbal', 'aliases' => array(), 'dev_requirement' => false, ), 'doctrine/deprecations' => array( - 'pretty_version' => '1.1.2', - 'version' => '1.1.2.0', - 'reference' => '4f2d4f2836e7ec4e7a8625e75c6aa916004db931', + 'pretty_version' => '1.1.3', + 'version' => '1.1.3.0', + 'reference' => 'dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab', 'type' => 'library', 'install_path' => __DIR__ . '/../doctrine/deprecations', 'aliases' => array(), @@ -319,7 +319,7 @@ 'nextcloud/3rdparty' => array( 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => '1d2219713ab10d22f2784178009c4d08b97a831e', + 'reference' => '0be1f7e31b14364f82dfdb5cd6c072479c176866', 'type' => 'library', 'install_path' => __DIR__ . '/../', 'aliases' => array(), diff --git a/doctrine/dbal/src/Connection.php b/doctrine/dbal/src/Connection.php index d84dc3158..76b427b5b 100644 --- a/doctrine/dbal/src/Connection.php +++ b/doctrine/dbal/src/Connection.php @@ -37,6 +37,7 @@ use function count; use function get_class; use function implode; +use function is_array; use function is_int; use function is_string; use function key; @@ -1137,6 +1138,10 @@ public function executeCacheQuery($sql, $params, $types, QueryCacheProfile $qcp) if ($item->isHit()) { $value = $item->get(); + if (! is_array($value)) { + $value = []; + } + if (isset($value[$realKey])) { return new Result(new ArrayResult($value[$realKey]), $this); } @@ -1336,7 +1341,7 @@ public function getNestTransactionsWithSavepoints() */ protected function _getNestedTransactionSavePointName() { - return 'DOCTRINE2_SAVEPOINT_' . $this->transactionNestingLevel; + return 'DOCTRINE_' . $this->transactionNestingLevel; } /** @@ -1794,7 +1799,7 @@ private function bindParameters(DriverStatement $stmt, array $params, array $typ 'doctrine/dbal', 'https://github.com/doctrine/dbal/pull/5550', 'Using NULL as prepared statement parameter type is deprecated.' - . 'Omit or use Parameter::STRING instead', + . 'Omit or use ParameterType::STRING instead', ); } @@ -1817,7 +1822,7 @@ private function bindParameters(DriverStatement $stmt, array $params, array $typ 'doctrine/dbal', 'https://github.com/doctrine/dbal/pull/5550', 'Using NULL as prepared statement parameter type is deprecated.' - . 'Omit or use Parameter::STRING instead', + . 'Omit or use ParameterType::STRING instead', ); } diff --git a/doctrine/dbal/src/Connections/PrimaryReadReplicaConnection.php b/doctrine/dbal/src/Connections/PrimaryReadReplicaConnection.php index 8cffb7fe6..2617fb802 100644 --- a/doctrine/dbal/src/Connections/PrimaryReadReplicaConnection.php +++ b/doctrine/dbal/src/Connections/PrimaryReadReplicaConnection.php @@ -67,8 +67,8 @@ * 'driver' => 'pdo_mysql', * 'primary' => array('user' => '', 'password' => '', 'host' => '', 'dbname' => ''), * 'replica' => array( - * array('user' => 'replica1', 'password', 'host' => '', 'dbname' => ''), - * array('user' => 'replica2', 'password', 'host' => '', 'dbname' => ''), + * array('user' => 'replica1', 'password' => '', 'host' => '', 'dbname' => ''), + * array('user' => 'replica2', 'password' => '', 'host' => '', 'dbname' => ''), * ) * )); * diff --git a/doctrine/dbal/src/Driver/AbstractMySQLDriver.php b/doctrine/dbal/src/Driver/AbstractMySQLDriver.php index 5f6ffd6f5..83159a540 100644 --- a/doctrine/dbal/src/Driver/AbstractMySQLDriver.php +++ b/doctrine/dbal/src/Driver/AbstractMySQLDriver.php @@ -11,6 +11,7 @@ use Doctrine\DBAL\Platforms\MariaDb1027Platform; use Doctrine\DBAL\Platforms\MariaDb1043Platform; use Doctrine\DBAL\Platforms\MariaDb1052Platform; +use Doctrine\DBAL\Platforms\MariaDb1060Platform; use Doctrine\DBAL\Platforms\MySQL57Platform; use Doctrine\DBAL\Platforms\MySQL80Platform; use Doctrine\DBAL\Platforms\MySQLPlatform; @@ -39,6 +40,10 @@ public function createDatabasePlatformForVersion($version) if ($mariadb) { $mariaDbVersion = $this->getMariaDbMysqlVersionNumber($version); + if (version_compare($mariaDbVersion, '10.6.0', '>=')) { + return new MariaDb1060Platform(); + } + if (version_compare($mariaDbVersion, '10.5.2', '>=')) { return new MariaDb1052Platform(); } diff --git a/doctrine/dbal/src/Driver/OCI8/Driver.php b/doctrine/dbal/src/Driver/OCI8/Driver.php index 53e563c63..650a4f9ab 100644 --- a/doctrine/dbal/src/Driver/OCI8/Driver.php +++ b/doctrine/dbal/src/Driver/OCI8/Driver.php @@ -4,9 +4,11 @@ use Doctrine\DBAL\Driver\AbstractOracleDriver; use Doctrine\DBAL\Driver\OCI8\Exception\ConnectionFailed; +use Doctrine\DBAL\Driver\OCI8\Exception\InvalidConfiguration; use SensitiveParameter; use function oci_connect; +use function oci_new_connect; use function oci_pconnect; use const OCI_NO_AUTO_COMMIT; @@ -32,8 +34,17 @@ public function connect( $connectionString = $this->getEasyConnectString($params); - if (! empty($params['persistent'])) { + $persistent = ! empty($params['persistent']); + $exclusive = ! empty($params['driverOptions']['exclusive']); + + if ($persistent && $exclusive) { + throw InvalidConfiguration::forPersistentAndExclusive(); + } + + if ($persistent) { $connection = @oci_pconnect($username, $password, $connectionString, $charset, $sessionMode); + } elseif ($exclusive) { + $connection = @oci_new_connect($username, $password, $connectionString, $charset, $sessionMode); } else { $connection = @oci_connect($username, $password, $connectionString, $charset, $sessionMode); } diff --git a/doctrine/dbal/src/Driver/OCI8/Exception/InvalidConfiguration.php b/doctrine/dbal/src/Driver/OCI8/Exception/InvalidConfiguration.php new file mode 100644 index 000000000..e9d2d0ebd --- /dev/null +++ b/doctrine/dbal/src/Driver/OCI8/Exception/InvalidConfiguration.php @@ -0,0 +1,20 @@ + $params['user'] ?? null, 'password' => $params['password'] ?? null, 'sslmode' => $params['sslmode'] ?? null, + 'gssencmode' => $params['gssencmode'] ?? null, ], static fn ($value) => $value !== '' && $value !== null, ); diff --git a/doctrine/dbal/src/Id/TableGenerator.php b/doctrine/dbal/src/Id/TableGenerator.php index 7d7f210e2..51e541d54 100644 --- a/doctrine/dbal/src/Id/TableGenerator.php +++ b/doctrine/dbal/src/Id/TableGenerator.php @@ -6,7 +6,6 @@ use Doctrine\DBAL\Driver; use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\Exception; -use Doctrine\DBAL\LockMode; use Doctrine\Deprecations\Deprecation; use Throwable; @@ -115,11 +114,13 @@ public function nextValue($sequence) $this->conn->beginTransaction(); try { - $platform = $this->conn->getDatabasePlatform(); - $sql = 'SELECT sequence_value, sequence_increment_by' - . ' FROM ' . $platform->appendLockHint($this->generatorTableName, LockMode::PESSIMISTIC_WRITE) - . ' WHERE sequence_name = ? ' . $platform->getWriteLockSQL(); - $row = $this->conn->fetchAssociative($sql, [$sequence]); + $row = $this->conn->createQueryBuilder() + ->select('sequence_value', 'sequence_increment_by') + ->from($this->generatorTableName) + ->where('sequence_name = ?') + ->forUpdate() + ->setParameter(1, $sequence) + ->fetchAssociative(); if ($row !== false) { $row = array_change_key_case($row, CASE_LOWER); diff --git a/doctrine/dbal/src/Platforms/AbstractMySQLPlatform.php b/doctrine/dbal/src/Platforms/AbstractMySQLPlatform.php index d1e3e5aff..8651b8278 100644 --- a/doctrine/dbal/src/Platforms/AbstractMySQLPlatform.php +++ b/doctrine/dbal/src/Platforms/AbstractMySQLPlatform.php @@ -11,6 +11,8 @@ use Doctrine\DBAL\Schema\MySQLSchemaManager; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; +use Doctrine\DBAL\SQL\Builder\DefaultSelectSQLBuilder; +use Doctrine\DBAL\SQL\Builder\SelectSQLBuilder; use Doctrine\DBAL\TransactionIsolationLevel; use Doctrine\DBAL\Types\BlobType; use Doctrine\DBAL\Types\TextType; @@ -398,6 +400,8 @@ public function getListTableColumnsSQL($table, $database = null) } /** + * @deprecated Use {@see getColumnTypeSQLSnippet()} instead. + * * The SQL snippets required to elucidate a column type * * Returns an array of the form [column type SELECT snippet, additional JOIN statement snippet] @@ -406,7 +410,24 @@ public function getListTableColumnsSQL($table, $database = null) */ public function getColumnTypeSQLSnippets(string $tableAlias = 'c'): array { - return [$tableAlias . '.COLUMN_TYPE', '']; + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6202', + 'AbstractMySQLPlatform::getColumnTypeSQLSnippets() is deprecated. ' + . 'Use AbstractMySQLPlatform::getColumnTypeSQLSnippet() instead.', + ); + + return [$this->getColumnTypeSQLSnippet(...func_get_args()), '']; + } + + /** + * The SQL snippet required to elucidate a column type + * + * Returns a column type SELECT snippet string + */ + public function getColumnTypeSQLSnippet(string $tableAlias = 'c', ?string $databaseName = null): string + { + return $tableAlias . '.COLUMN_TYPE'; } /** @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. */ @@ -522,6 +543,11 @@ protected function _getCreateTableSQL($name, array $columns, array $options = [] return $sql; } + public function createSelectSQLBuilder(): SelectSQLBuilder + { + return new DefaultSelectSQLBuilder($this, 'FOR UPDATE', null); + } + /** * {@inheritDoc} * @@ -1403,8 +1429,16 @@ public function supportsColumnLengthIndexes(): bool return true; } + /** @deprecated Will be removed without replacement. */ protected function getDatabaseNameSQL(?string $databaseName): string { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6215', + '%s is deprecated without replacement.', + __METHOD__, + ); + if ($databaseName !== null) { return $this->quoteStringLiteral($databaseName); } diff --git a/doctrine/dbal/src/Platforms/AbstractPlatform.php b/doctrine/dbal/src/Platforms/AbstractPlatform.php index eba3aefc8..49e131552 100644 --- a/doctrine/dbal/src/Platforms/AbstractPlatform.php +++ b/doctrine/dbal/src/Platforms/AbstractPlatform.php @@ -29,6 +29,8 @@ use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; use Doctrine\DBAL\Schema\UniqueConstraint; +use Doctrine\DBAL\SQL\Builder\DefaultSelectSQLBuilder; +use Doctrine\DBAL\SQL\Builder\SelectSQLBuilder; use Doctrine\DBAL\SQL\Parser; use Doctrine\DBAL\TransactionIsolationLevel; use Doctrine\DBAL\Types; @@ -211,6 +213,7 @@ private function initializeAllDoctrineTypeMappings(): void foreach (Type::getTypesMap() as $typeName => $className) { foreach (Type::getType($typeName)->getMappedDatabaseTypes($this) as $dbType) { + $dbType = strtolower($dbType); $this->doctrineTypeMapping[$dbType] = $typeName; } } @@ -1340,8 +1343,8 @@ public function getDateDiffExpression($date1, $date2) /** * Returns the SQL to add the number of given seconds to a date. * - * @param string $date - * @param int|numeric-string $seconds + * @param string $date + * @param int|string $seconds * * @return string * @@ -1363,8 +1366,8 @@ public function getDateAddSecondsExpression($date, $seconds) /** * Returns the SQL to subtract the number of given seconds from a date. * - * @param string $date - * @param int|numeric-string $seconds + * @param string $date + * @param int|string $seconds * * @return string * @@ -1386,8 +1389,8 @@ public function getDateSubSecondsExpression($date, $seconds) /** * Returns the SQL to add the number of given minutes to a date. * - * @param string $date - * @param int|numeric-string $minutes + * @param string $date + * @param int|string $minutes * * @return string * @@ -1409,8 +1412,8 @@ public function getDateAddMinutesExpression($date, $minutes) /** * Returns the SQL to subtract the number of given minutes from a date. * - * @param string $date - * @param int|numeric-string $minutes + * @param string $date + * @param int|string $minutes * * @return string * @@ -1432,8 +1435,8 @@ public function getDateSubMinutesExpression($date, $minutes) /** * Returns the SQL to add the number of given hours to a date. * - * @param string $date - * @param int|numeric-string $hours + * @param string $date + * @param int|string $hours * * @return string * @@ -1455,8 +1458,8 @@ public function getDateAddHourExpression($date, $hours) /** * Returns the SQL to subtract the number of given hours to a date. * - * @param string $date - * @param int|numeric-string $hours + * @param string $date + * @param int|string $hours * * @return string * @@ -1478,8 +1481,8 @@ public function getDateSubHourExpression($date, $hours) /** * Returns the SQL to add the number of given days to a date. * - * @param string $date - * @param int|numeric-string $days + * @param string $date + * @param int|string $days * * @return string * @@ -1501,8 +1504,8 @@ public function getDateAddDaysExpression($date, $days) /** * Returns the SQL to subtract the number of given days to a date. * - * @param string $date - * @param int|numeric-string $days + * @param string $date + * @param int|string $days * * @return string * @@ -1524,8 +1527,8 @@ public function getDateSubDaysExpression($date, $days) /** * Returns the SQL to add the number of given weeks to a date. * - * @param string $date - * @param int|numeric-string $weeks + * @param string $date + * @param int|string $weeks * * @return string * @@ -1547,8 +1550,8 @@ public function getDateAddWeeksExpression($date, $weeks) /** * Returns the SQL to subtract the number of given weeks from a date. * - * @param string $date - * @param int|numeric-string $weeks + * @param string $date + * @param int|string $weeks * * @return string * @@ -1570,8 +1573,8 @@ public function getDateSubWeeksExpression($date, $weeks) /** * Returns the SQL to add the number of given months to a date. * - * @param string $date - * @param int|numeric-string $months + * @param string $date + * @param int|string $months * * @return string * @@ -1593,8 +1596,8 @@ public function getDateAddMonthExpression($date, $months) /** * Returns the SQL to subtract the number of given months to a date. * - * @param string $date - * @param int|numeric-string $months + * @param string $date + * @param int|string $months * * @return string * @@ -1616,8 +1619,8 @@ public function getDateSubMonthExpression($date, $months) /** * Returns the SQL to add the number of given quarters to a date. * - * @param string $date - * @param int|numeric-string $quarters + * @param string $date + * @param int|string $quarters * * @return string * @@ -1639,8 +1642,8 @@ public function getDateAddQuartersExpression($date, $quarters) /** * Returns the SQL to subtract the number of given quarters from a date. * - * @param string $date - * @param int|numeric-string $quarters + * @param string $date + * @param int|string $quarters * * @return string * @@ -1662,8 +1665,8 @@ public function getDateSubQuartersExpression($date, $quarters) /** * Returns the SQL to add the number of given years to a date. * - * @param string $date - * @param int|numeric-string $years + * @param string $date + * @param int|string $years * * @return string * @@ -1685,8 +1688,8 @@ public function getDateAddYearsExpression($date, $years) /** * Returns the SQL to subtract the number of given years from a date. * - * @param string $date - * @param int|numeric-string $years + * @param string $date + * @param int|string $years * * @return string * @@ -1708,11 +1711,11 @@ public function getDateSubYearsExpression($date, $years) /** * Returns the SQL for a date arithmetic expression. * - * @param string $date The column or literal representing a date + * @param string $date The column or literal representing a date * to perform the arithmetic operation on. - * @param string $operator The arithmetic operator (+ or -). - * @param int|numeric-string $interval The interval that shall be calculated into the date. - * @param string $unit The unit of the interval that shall be calculated into the date. + * @param string $operator The arithmetic operator (+ or -). + * @param int|string $interval The interval that shall be calculated into the date. + * @param string $unit The unit of the interval that shall be calculated into the date. * One of the {@see DateIntervalUnit} constants. * * @return string @@ -1724,6 +1727,17 @@ protected function getDateArithmeticIntervalExpression($date, $operator, $interv throw Exception::notSupported(__METHOD__); } + /** + * Generates the SQL expression which represents the given date interval multiplied by a number + * + * @param string $interval SQL expression describing the interval value + * @param int $multiplier Interval multiplier + */ + protected function multiplyInterval(string $interval, int $multiplier): string + { + return sprintf('(%s * %d)', $interval, $multiplier); + } + /** * Returns the SQL bit AND comparison expression. * @@ -1758,10 +1772,19 @@ abstract public function getCurrentDatabaseExpression(): string; /** * Returns the FOR UPDATE expression. * + * @deprecated This API is not portable. Use {@link QueryBuilder::forUpdate()}` instead. + * * @return string */ public function getForUpdateSQL() { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6191', + '%s is deprecated as non-portable.', + __METHOD__, + ); + return 'FOR UPDATE'; } @@ -1793,10 +1816,19 @@ public function appendLockHint(string $fromClause, int $lockMode): string * This defaults to the ANSI SQL "FOR UPDATE", which is an exclusive lock (Write). Some database * vendors allow to lighten this constraint up to be a real read lock. * + * @deprecated This API is not portable. + * * @return string */ public function getReadLockSQL() { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6191', + '%s is deprecated as non-portable.', + __METHOD__, + ); + return $this->getForUpdateSQL(); } @@ -1805,10 +1837,19 @@ public function getReadLockSQL() * * The semantics of this lock mode should equal the SELECT .. FOR UPDATE of the ANSI SQL standard. * + * @deprecated This API is not portable. + * * @return string */ public function getWriteLockSQL() { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6191', + '%s is deprecated as non-portable.', + __METHOD__, + ); + return $this->getForUpdateSQL(); } @@ -2052,6 +2093,11 @@ public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDE ); } + public function createSelectSQLBuilder(): SelectSQLBuilder + { + return new DefaultSelectSQLBuilder($this, 'FOR UPDATE', 'SKIP LOCKED'); + } + /** * @internal * diff --git a/doctrine/dbal/src/Platforms/DB2Platform.php b/doctrine/dbal/src/Platforms/DB2Platform.php index b203ce8a0..69234f410 100644 --- a/doctrine/dbal/src/Platforms/DB2Platform.php +++ b/doctrine/dbal/src/Platforms/DB2Platform.php @@ -9,6 +9,8 @@ use Doctrine\DBAL\Schema\Identifier; use Doctrine\DBAL\Schema\Index; use Doctrine\DBAL\Schema\TableDiff; +use Doctrine\DBAL\SQL\Builder\DefaultSelectSQLBuilder; +use Doctrine\DBAL\SQL\Builder\SelectSQLBuilder; use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Types; use Doctrine\Deprecations\Deprecation; @@ -291,13 +293,13 @@ protected function getDateArithmeticIntervalExpression($date, $operator, $interv { switch ($unit) { case DateIntervalUnit::WEEK: - $interval *= 7; - $unit = DateIntervalUnit::DAY; + $interval = $this->multiplyInterval((string) $interval, 7); + $unit = DateIntervalUnit::DAY; break; case DateIntervalUnit::QUARTER: - $interval *= 3; - $unit = DateIntervalUnit::MONTH; + $interval = $this->multiplyInterval((string) $interval, 3); + $unit = DateIntervalUnit::MONTH; break; } @@ -974,8 +976,15 @@ public function prefersIdentityColumns() return true; } + public function createSelectSQLBuilder(): SelectSQLBuilder + { + return new DefaultSelectSQLBuilder($this, 'WITH RR USE AND KEEP UPDATE LOCKS', null); + } + /** * {@inheritDoc} + * + * @deprecated This API is not portable. */ public function getForUpdateSQL() { diff --git a/doctrine/dbal/src/Platforms/MariaDb1043Platform.php b/doctrine/dbal/src/Platforms/MariaDb1043Platform.php index 926c6b952..9076b41d4 100644 --- a/doctrine/dbal/src/Platforms/MariaDb1043Platform.php +++ b/doctrine/dbal/src/Platforms/MariaDb1043Platform.php @@ -3,6 +3,7 @@ namespace Doctrine\DBAL\Platforms; use Doctrine\DBAL\Types\JsonType; +use Doctrine\Deprecations\Deprecation; use function sprintf; @@ -40,7 +41,8 @@ public function getJsonTypeDeclarationSQL(array $column): string */ public function getListTableColumnsSQL($table, $database = null): string { - [$columnTypeSQL, $joinCheckConstraintSQL] = $this->getColumnTypeSQLSnippets(); + // @todo 4.0 - call getColumnTypeSQLSnippet() instead + [$columnTypeSQL, $joinCheckConstraintSQL] = $this->getColumnTypeSQLSnippets('c', $database); return sprintf( <<getJsonTypeDeclarationSQL([]) !== 'JSON') { - return parent::getColumnTypeSQLSnippets($tableAlias); + return parent::getColumnTypeSQLSnippet($tableAlias, $databaseName); + } + + if ($databaseName === null) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6215', + 'Not passing a database name to methods "getColumnTypeSQLSnippet()", ' + . '"getColumnTypeSQLSnippets()", and "getListTableColumnsSQL()" of "%s" is deprecated.', + self::class, + ); } - $columnTypeSQL = <<getDatabaseNameSQL($databaseName); + + // The check for `CONSTRAINT_SCHEMA = $databaseName` is mandatory here to prevent performance issues + return <<multiplyInterval((string) $interval, 3); break; case DateIntervalUnit::YEAR: - $interval *= 12; + $interval = $this->multiplyInterval((string) $interval, 12); break; } diff --git a/doctrine/dbal/src/Platforms/PostgreSQL100Platform.php b/doctrine/dbal/src/Platforms/PostgreSQL100Platform.php index aa023ba79..6ee1f90f2 100644 --- a/doctrine/dbal/src/Platforms/PostgreSQL100Platform.php +++ b/doctrine/dbal/src/Platforms/PostgreSQL100Platform.php @@ -5,6 +5,7 @@ namespace Doctrine\DBAL\Platforms; use Doctrine\DBAL\Platforms\Keywords\PostgreSQL100Keywords; +use Doctrine\DBAL\SQL\Builder\SelectSQLBuilder; use Doctrine\Deprecations\Deprecation; /** @@ -27,4 +28,9 @@ protected function getReservedKeywordsClass(): string return PostgreSQL100Keywords::class; } + + public function createSelectSQLBuilder(): SelectSQLBuilder + { + return AbstractPlatform::createSelectSQLBuilder(); + } } diff --git a/doctrine/dbal/src/Platforms/PostgreSQLPlatform.php b/doctrine/dbal/src/Platforms/PostgreSQLPlatform.php index 9e6648cbd..336483848 100644 --- a/doctrine/dbal/src/Platforms/PostgreSQLPlatform.php +++ b/doctrine/dbal/src/Platforms/PostgreSQLPlatform.php @@ -12,6 +12,8 @@ use Doctrine\DBAL\Schema\Sequence; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; +use Doctrine\DBAL\SQL\Builder\DefaultSelectSQLBuilder; +use Doctrine\DBAL\SQL\Builder\SelectSQLBuilder; use Doctrine\DBAL\Types\BinaryType; use Doctrine\DBAL\Types\BlobType; use Doctrine\DBAL\Types\Types; @@ -134,8 +136,8 @@ public function getLocateExpression($str, $substr, $startPos = false) protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit) { if ($unit === DateIntervalUnit::QUARTER) { - $interval *= 3; - $unit = DateIntervalUnit::MONTH; + $interval = $this->multiplyInterval((string) $interval, 3); + $unit = DateIntervalUnit::MONTH; } return '(' . $date . ' ' . $operator . ' (' . $interval . " || ' " . $unit . "')::interval)"; @@ -266,6 +268,11 @@ public function hasNativeGuidType() return true; } + public function createSelectSQLBuilder(): SelectSQLBuilder + { + return new DefaultSelectSQLBuilder($this, 'FOR UPDATE', null); + } + /** * {@inheritDoc} * diff --git a/doctrine/dbal/src/Platforms/SQLServer/SQL/Builder/SQLServerSelectSQLBuilder.php b/doctrine/dbal/src/Platforms/SQLServer/SQL/Builder/SQLServerSelectSQLBuilder.php new file mode 100644 index 000000000..dff12221c --- /dev/null +++ b/doctrine/dbal/src/Platforms/SQLServer/SQL/Builder/SQLServerSelectSQLBuilder.php @@ -0,0 +1,86 @@ +platform = $platform; + } + + public function buildSQL(SelectQuery $query): string + { + $parts = ['SELECT']; + + if ($query->isDistinct()) { + $parts[] = 'DISTINCT'; + } + + $parts[] = implode(', ', $query->getColumns()); + + $from = $query->getFrom(); + + if (count($from) > 0) { + $parts[] = 'FROM ' . implode(', ', $from); + } + + $forUpdate = $query->getForUpdate(); + + if ($forUpdate !== null) { + $with = ['UPDLOCK', 'ROWLOCK']; + + if ($forUpdate->getConflictResolutionMode() === ConflictResolutionMode::SKIP_LOCKED) { + $with[] = 'READPAST'; + } + + $parts[] = 'WITH (' . implode(', ', $with) . ')'; + } + + $where = $query->getWhere(); + + if ($where !== null) { + $parts[] = 'WHERE ' . $where; + } + + $groupBy = $query->getGroupBy(); + + if (count($groupBy) > 0) { + $parts[] = 'GROUP BY ' . implode(', ', $groupBy); + } + + $having = $query->getHaving(); + + if ($having !== null) { + $parts[] = 'HAVING ' . $having; + } + + $orderBy = $query->getOrderBy(); + + if (count($orderBy) > 0) { + $parts[] = 'ORDER BY ' . implode(', ', $orderBy); + } + + $sql = implode(' ', $parts); + $limit = $query->getLimit(); + + if ($limit->isDefined()) { + $sql = $this->platform->modifyLimitQuery($sql, $limit->getMaxResults(), $limit->getFirstResult()); + } + + return $sql; + } +} diff --git a/doctrine/dbal/src/Platforms/SQLServerPlatform.php b/doctrine/dbal/src/Platforms/SQLServerPlatform.php index 113055ba8..c8cd20b56 100644 --- a/doctrine/dbal/src/Platforms/SQLServerPlatform.php +++ b/doctrine/dbal/src/Platforms/SQLServerPlatform.php @@ -5,6 +5,7 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\Exception\InvalidLockMode; use Doctrine\DBAL\LockMode; +use Doctrine\DBAL\Platforms\SQLServer\SQL\Builder\SQLServerSelectSQLBuilder; use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\ColumnDiff; use Doctrine\DBAL\Schema\ForeignKeyConstraint; @@ -14,6 +15,7 @@ use Doctrine\DBAL\Schema\SQLServerSchemaManager; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; +use Doctrine\DBAL\SQL\Builder\SelectSQLBuilder; use Doctrine\DBAL\Types\Types; use Doctrine\Deprecations\Deprecation; use InvalidArgumentException; @@ -49,6 +51,11 @@ */ class SQLServerPlatform extends AbstractPlatform { + public function createSelectSQLBuilder(): SelectSQLBuilder + { + return new SQLServerSelectSQLBuilder($this); + } + /** * {@inheritDoc} */ @@ -1610,6 +1617,8 @@ public function appendLockHint(string $fromClause, int $lockMode): string /** * {@inheritDoc} + * + * @deprecated This API is not portable. */ public function getForUpdateSQL() { diff --git a/doctrine/dbal/src/Platforms/SqlitePlatform.php b/doctrine/dbal/src/Platforms/SqlitePlatform.php index 5acefc5c8..ea9a44413 100644 --- a/doctrine/dbal/src/Platforms/SqlitePlatform.php +++ b/doctrine/dbal/src/Platforms/SqlitePlatform.php @@ -14,10 +14,13 @@ use Doctrine\DBAL\Schema\SqliteSchemaManager; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; +use Doctrine\DBAL\SQL\Builder\DefaultSelectSQLBuilder; +use Doctrine\DBAL\SQL\Builder\SelectSQLBuilder; use Doctrine\DBAL\TransactionIsolationLevel; use Doctrine\DBAL\Types; use Doctrine\DBAL\Types\IntegerType; use Doctrine\Deprecations\Deprecation; +use InvalidArgumentException; use function array_combine; use function array_keys; @@ -26,12 +29,14 @@ use function array_unique; use function array_values; use function count; +use function explode; use function implode; use function is_numeric; use function sprintf; use function sqrt; use function str_replace; use function strlen; +use function strpos; use function strtolower; use function trim; @@ -154,13 +159,13 @@ protected function getDateArithmeticIntervalExpression($date, $operator, $interv switch ($unit) { case DateIntervalUnit::WEEK: - $interval *= 7; - $unit = DateIntervalUnit::DAY; + $interval = $this->multiplyInterval((string) $interval, 7); + $unit = DateIntervalUnit::DAY; break; case DateIntervalUnit::QUARTER: - $interval *= 3; - $unit = DateIntervalUnit::MONTH; + $interval = $this->multiplyInterval((string) $interval, 3); + $unit = DateIntervalUnit::MONTH; break; } @@ -193,6 +198,12 @@ public function getCurrentDatabaseExpression(): string return "'main'"; } + /** @link https://www2.sqlite.org/cvstrac/wiki?p=UnsupportedSql */ + public function createSelectSQLBuilder(): SelectSQLBuilder + { + return new DefaultSelectSQLBuilder($this, null, null); + } + /** * {@inheritDoc} */ @@ -734,6 +745,8 @@ public static function udfLocate($str, $substr, $offset = 0) /** * {@inheritDoc} + * + * @deprecated This API is not portable. */ public function getForUpdateSQL() { @@ -918,6 +931,48 @@ public function getCreateTablesSQL(array $tables): array return $sql; } + /** + * {@inheritDoc} + */ + public function getCreateIndexSQL(Index $index, $table) + { + if ($table instanceof Table) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $table as a Table object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + + $table = $table->getQuotedName($this); + } + + $name = $index->getQuotedName($this); + $columns = $index->getColumns(); + + if (strpos($table, '.') !== false) { + [$schema, $table] = explode('.', $table); + $name = $schema . '.' . $name; + } + + if (count($columns) === 0) { + throw new InvalidArgumentException(sprintf( + 'Incomplete or invalid index definition %s on table %s', + $name, + $table, + )); + } + + if ($index->isPrimary()) { + return $this->getCreatePrimaryKeySQL($index, $table); + } + + $query = 'CREATE ' . $this->getCreateIndexSQLFlags($index) . 'INDEX ' . $name . ' ON ' . $table; + $query .= ' (' . $this->getIndexFieldDeclarationListSQL($index) . ')' . $this->getPartialIndexSQL($index); + + return $query; + } + /** * {@inheritDoc} */ diff --git a/doctrine/dbal/src/Query/Expression/CompositeExpression.php b/doctrine/dbal/src/Query/Expression/CompositeExpression.php index de1d929a0..4cad8ec1d 100644 --- a/doctrine/dbal/src/Query/Expression/CompositeExpression.php +++ b/doctrine/dbal/src/Query/Expression/CompositeExpression.php @@ -149,6 +149,7 @@ public function with($part, ...$parts): self * Retrieves the amount of expressions on composite expression. * * @return int + * @psalm-return int<0, max> */ #[ReturnTypeWillChange] public function count() diff --git a/doctrine/dbal/src/Query/ForUpdate.php b/doctrine/dbal/src/Query/ForUpdate.php new file mode 100644 index 000000000..fe54df909 --- /dev/null +++ b/doctrine/dbal/src/Query/ForUpdate.php @@ -0,0 +1,21 @@ +conflictResolutionMode = $conflictResolutionMode; + } + + public function getConflictResolutionMode(): int + { + return $this->conflictResolutionMode; + } +} diff --git a/doctrine/dbal/src/Query/ForUpdate/ConflictResolutionMode.php b/doctrine/dbal/src/Query/ForUpdate/ConflictResolutionMode.php new file mode 100644 index 000000000..f968f7b94 --- /dev/null +++ b/doctrine/dbal/src/Query/ForUpdate/ConflictResolutionMode.php @@ -0,0 +1,27 @@ +maxResults = $maxResults; + $this->firstResult = $firstResult; + } + + public function isDefined(): bool + { + return $this->maxResults !== null || $this->firstResult !== 0; + } + + public function getMaxResults(): ?int + { + return $this->maxResults; + } + + public function getFirstResult(): int + { + return $this->firstResult; + } +} diff --git a/doctrine/dbal/src/Query/QueryBuilder.php b/doctrine/dbal/src/Query/QueryBuilder.php index ba76fdf93..f099e756b 100644 --- a/doctrine/dbal/src/Query/QueryBuilder.php +++ b/doctrine/dbal/src/Query/QueryBuilder.php @@ -8,6 +8,7 @@ use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\Query\Expression\CompositeExpression; use Doctrine\DBAL\Query\Expression\ExpressionBuilder; +use Doctrine\DBAL\Query\ForUpdate\ConflictResolutionMode; use Doctrine\DBAL\Result; use Doctrine\DBAL\Statement; use Doctrine\DBAL\Types\Type; @@ -17,14 +18,17 @@ use function array_keys; use function array_unshift; use function count; +use function func_get_arg; use function func_get_args; use function func_num_args; use function implode; use function is_array; use function is_object; use function key; +use function method_exists; use function strtoupper; use function substr; +use function ucfirst; /** * QueryBuilder class is responsible to dynamically create SQL queries. @@ -35,6 +39,8 @@ * The query builder does no validation whatsoever if certain features even work with the * underlying database vendor. Limit queries and joins are NOT applied to UPDATE and DELETE statements * even if some vendors such as MySQL support it. + * + * @method $this distinct(bool $distinct = true) Adds or removes DISTINCT to/from the query. */ class QueryBuilder { @@ -65,16 +71,17 @@ class QueryBuilder * The default values of SQL parts collection */ private const SQL_PARTS_DEFAULTS = [ - 'select' => [], - 'distinct' => false, - 'from' => [], - 'join' => [], - 'set' => [], - 'where' => null, - 'groupBy' => [], - 'having' => null, - 'orderBy' => [], - 'values' => [], + 'select' => [], + 'distinct' => false, + 'from' => [], + 'join' => [], + 'set' => [], + 'where' => null, + 'groupBy' => [], + 'having' => null, + 'orderBy' => [], + 'values' => [], + 'for_update' => null, ]; /** @@ -454,7 +461,7 @@ public function setParameter($key, $value, $type = ParameterType::STRING) 'doctrine/dbal', 'https://github.com/doctrine/dbal/pull/5550', 'Using NULL as prepared statement parameter type is deprecated.' - . 'Omit or use Parameter::STRING instead', + . 'Omit or use ParameterType::STRING instead', ); } @@ -586,6 +593,20 @@ public function getMaxResults() return $this->maxResults; } + /** + * Locks the queried rows for a subsequent update. + * + * @return $this + */ + public function forUpdate(int $conflictResolutionMode = ConflictResolutionMode::ORDINARY): self + { + $this->state = self::STATE_DIRTY; + + $this->sqlParts['for_update'] = new ForUpdate($conflictResolutionMode); + + return $this; + } + /** * Either appends to or replaces a single, generic query part. * @@ -677,7 +698,7 @@ public function select($select = null/*, string ...$selects*/) } /** - * Adds DISTINCT to the query. + * Adds or removes DISTINCT to/from the query. * * * $qb = $conn->createQueryBuilder() @@ -688,9 +709,10 @@ public function select($select = null/*, string ...$selects*/) * * @return $this This QueryBuilder instance. */ - public function distinct(): self + public function distinct(/* bool $distinct = true */): self { - $this->sqlParts['distinct'] = true; + $this->sqlParts['distinct'] = func_num_args() < 1 || func_get_arg(0); + $this->state = self::STATE_DIRTY; return $this; } @@ -1297,52 +1319,115 @@ public function addOrderBy($sort, $order = null) /** * Gets a query part by its name. * + * @deprecated The query parts are implementation details and should not be relied upon. + * * @param string $queryPartName * * @return mixed */ public function getQueryPart($queryPartName) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6179', + 'Getting query parts is deprecated as they are implementation details.', + ); + return $this->sqlParts[$queryPartName]; } /** * Gets all query parts. * + * @deprecated The query parts are implementation details and should not be relied upon. + * * @return mixed[] */ public function getQueryParts() { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6179', + 'Getting query parts is deprecated as they are implementation details.', + ); + return $this->sqlParts; } /** * Resets SQL parts. * + * @deprecated Use the dedicated reset*() methods instead. + * * @param string[]|null $queryPartNames * * @return $this This QueryBuilder instance. */ public function resetQueryParts($queryPartNames = null) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6193', + '%s() is deprecated, instead use dedicated reset methods for the parts that shall be reset.', + __METHOD__, + ); + $queryPartNames ??= array_keys($this->sqlParts); foreach ($queryPartNames as $queryPartName) { - $this->resetQueryPart($queryPartName); + $this->sqlParts[$queryPartName] = self::SQL_PARTS_DEFAULTS[$queryPartName]; } + $this->state = self::STATE_DIRTY; + return $this; } /** * Resets a single SQL part. * + * @deprecated Use the dedicated reset*() methods instead. + * * @param string $queryPartName * * @return $this This QueryBuilder instance. */ public function resetQueryPart($queryPartName) { + if ($queryPartName === 'distinct') { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6193', + 'Calling %s() with "distinct" is deprecated, call distinct(false) instead.', + __METHOD__, + ); + + return $this->distinct(false); + } + + $newMethodName = 'reset' . ucfirst($queryPartName); + if (array_key_exists($queryPartName, self::SQL_PARTS_DEFAULTS) && method_exists($this, $newMethodName)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6193', + 'Calling %s() with "%s" is deprecated, call %s() instead.', + __METHOD__, + $queryPartName, + $newMethodName, + ); + + return $this->$newMethodName(); + } + + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6193', + 'Calling %s() with "%s" is deprecated without replacement.', + __METHOD__, + $queryPartName, + $newMethodName, + ); + $this->sqlParts[$queryPartName] = self::SQL_PARTS_DEFAULTS[$queryPartName]; $this->state = self::STATE_DIRTY; @@ -1350,27 +1435,80 @@ public function resetQueryPart($queryPartName) return $this; } - /** @throws QueryException */ - private function getSQLForSelect(): string + /** + * Resets the WHERE conditions for the query. + * + * @return $this This QueryBuilder instance. + */ + public function resetWhere(): self { - $query = 'SELECT ' . ($this->sqlParts['distinct'] ? 'DISTINCT ' : '') . - implode(', ', $this->sqlParts['select']); + $this->sqlParts['where'] = self::SQL_PARTS_DEFAULTS['where']; - $query .= ($this->sqlParts['from'] ? ' FROM ' . implode(', ', $this->getFromClauses()) : '') - . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '') - . ($this->sqlParts['groupBy'] ? ' GROUP BY ' . implode(', ', $this->sqlParts['groupBy']) : '') - . ($this->sqlParts['having'] !== null ? ' HAVING ' . ((string) $this->sqlParts['having']) : '') - . ($this->sqlParts['orderBy'] ? ' ORDER BY ' . implode(', ', $this->sqlParts['orderBy']) : ''); + $this->state = self::STATE_DIRTY; - if ($this->isLimitQuery()) { - return $this->connection->getDatabasePlatform()->modifyLimitQuery( - $query, - $this->maxResults, - $this->firstResult, - ); - } + return $this; + } + + /** + * Resets the grouping for the query. + * + * @return $this This QueryBuilder instance. + */ + public function resetGroupBy(): self + { + $this->sqlParts['groupBy'] = self::SQL_PARTS_DEFAULTS['groupBy']; + + $this->state = self::STATE_DIRTY; + + return $this; + } + + /** + * Resets the HAVING conditions for the query. + * + * @return $this This QueryBuilder instance. + */ + public function resetHaving(): self + { + $this->sqlParts['having'] = self::SQL_PARTS_DEFAULTS['having']; + + $this->state = self::STATE_DIRTY; + + return $this; + } + + /** + * Resets the ordering for the query. + * + * @return $this This QueryBuilder instance. + */ + public function resetOrderBy(): self + { + $this->sqlParts['orderBy'] = self::SQL_PARTS_DEFAULTS['orderBy']; + + $this->state = self::STATE_DIRTY; + + return $this; + } - return $query; + /** @throws Exception */ + private function getSQLForSelect(): string + { + return $this->connection->getDatabasePlatform() + ->createSelectSQLBuilder() + ->buildSQL( + new SelectQuery( + $this->sqlParts['distinct'], + $this->sqlParts['select'], + $this->getFromClauses(), + $this->sqlParts['where'], + $this->sqlParts['groupBy'], + $this->sqlParts['having'], + $this->sqlParts['orderBy'], + new Limit($this->maxResults, $this->firstResult), + $this->sqlParts['for_update'], + ), + ); } /** @@ -1417,11 +1555,6 @@ private function verifyAllAliasesAreKnown(array $knownAliases): void } } - private function isLimitQuery(): bool - { - return $this->maxResults !== null || $this->firstResult !== 0; - } - /** * Converts this instance into an INSERT string in SQL. */ diff --git a/doctrine/dbal/src/Query/SelectQuery.php b/doctrine/dbal/src/Query/SelectQuery.php new file mode 100644 index 000000000..ed9a7bc2d --- /dev/null +++ b/doctrine/dbal/src/Query/SelectQuery.php @@ -0,0 +1,107 @@ +distinct = $distinct; + $this->columns = $columns; + $this->from = $from; + $this->where = $where; + $this->groupBy = $groupBy; + $this->having = $having; + $this->orderBy = $orderBy; + $this->limit = $limit; + $this->forUpdate = $forUpdate; + } + + public function isDistinct(): bool + { + return $this->distinct; + } + + /** @return string[] */ + public function getColumns(): array + { + return $this->columns; + } + + /** @return string[] */ + public function getFrom(): array + { + return $this->from; + } + + public function getWhere(): ?string + { + return $this->where; + } + + /** @return string[] */ + public function getGroupBy(): array + { + return $this->groupBy; + } + + public function getHaving(): ?string + { + return $this->having; + } + + /** @return string[] */ + public function getOrderBy(): array + { + return $this->orderBy; + } + + public function getLimit(): Limit + { + return $this->limit; + } + + public function getForUpdate(): ?ForUpdate + { + return $this->forUpdate; + } +} diff --git a/doctrine/dbal/src/SQL/Builder/DefaultSelectSQLBuilder.php b/doctrine/dbal/src/SQL/Builder/DefaultSelectSQLBuilder.php new file mode 100644 index 000000000..9dcb7a197 --- /dev/null +++ b/doctrine/dbal/src/SQL/Builder/DefaultSelectSQLBuilder.php @@ -0,0 +1,95 @@ +platform = $platform; + $this->forUpdateSQL = $forUpdateSQL; + $this->skipLockedSQL = $skipLockedSQL; + } + + /** @throws Exception */ + public function buildSQL(SelectQuery $query): string + { + $parts = ['SELECT']; + + if ($query->isDistinct()) { + $parts[] = 'DISTINCT'; + } + + $parts[] = implode(', ', $query->getColumns()); + + $from = $query->getFrom(); + + if (count($from) > 0) { + $parts[] = 'FROM ' . implode(', ', $from); + } + + $where = $query->getWhere(); + + if ($where !== null) { + $parts[] = 'WHERE ' . $where; + } + + $groupBy = $query->getGroupBy(); + + if (count($groupBy) > 0) { + $parts[] = 'GROUP BY ' . implode(', ', $groupBy); + } + + $having = $query->getHaving(); + + if ($having !== null) { + $parts[] = 'HAVING ' . $having; + } + + $orderBy = $query->getOrderBy(); + + if (count($orderBy) > 0) { + $parts[] = 'ORDER BY ' . implode(', ', $orderBy); + } + + $sql = implode(' ', $parts); + $limit = $query->getLimit(); + + if ($limit->isDefined()) { + $sql = $this->platform->modifyLimitQuery($sql, $limit->getMaxResults(), $limit->getFirstResult()); + } + + $forUpdate = $query->getForUpdate(); + + if ($forUpdate !== null) { + if ($this->forUpdateSQL === null) { + throw Exception::notSupported('FOR UPDATE'); + } + + $sql .= ' ' . $this->forUpdateSQL; + + if ($forUpdate->getConflictResolutionMode() === ConflictResolutionMode::SKIP_LOCKED) { + if ($this->skipLockedSQL === null) { + throw Exception::notSupported('SKIP LOCKED'); + } + + $sql .= ' ' . $this->skipLockedSQL; + } + } + + return $sql; + } +} diff --git a/doctrine/dbal/src/SQL/Builder/SelectSQLBuilder.php b/doctrine/dbal/src/SQL/Builder/SelectSQLBuilder.php new file mode 100644 index 000000000..ddbf73c03 --- /dev/null +++ b/doctrine/dbal/src/SQL/Builder/SelectSQLBuilder.php @@ -0,0 +1,12 @@ +_notnull; } - /** @return string|null */ + /** @return mixed */ public function getDefault() { return $this->_default; diff --git a/doctrine/dbal/src/Schema/MySQLSchemaManager.php b/doctrine/dbal/src/Schema/MySQLSchemaManager.php index 5faae24fa..3c00d00e2 100644 --- a/doctrine/dbal/src/Schema/MySQLSchemaManager.php +++ b/doctrine/dbal/src/Schema/MySQLSchemaManager.php @@ -191,12 +191,6 @@ protected function _getPortableTableColumnDefinition($tableColumn) $tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type); } - // Check underlying database type where doctrine type is inferred from DC2Type comment - // and set a flag if it is not as expected. - if ($origType !== $type && $this->expectedDbType($type, $tableColumn) !== $dbType) { - $tableColumn['declarationMismatch'] = true; - } - switch ($dbType) { case 'char': case 'binary': @@ -296,6 +290,12 @@ protected function _getPortableTableColumnDefinition($tableColumn) $column->setPlatformOption('declarationMismatch', $tableColumn['declarationMismatch']); } + // Check underlying database type where doctrine type is inferred from DC2Type comment + // and set a flag if it is not as expected. + if ($type === 'json' && $origType !== $type && $this->expectedDbType($type, $options) !== $dbType) { + $column->setPlatformOption('declarationMismatch', true); + } + return $column; } @@ -437,7 +437,8 @@ protected function selectTableNames(string $databaseName): Result protected function selectTableColumns(string $databaseName, ?string $tableName = null): Result { - [$columnTypeSQL, $joinCheckConstraintSQL] = $this->_platform->getColumnTypeSQLSnippets(); + // @todo 4.0 - call getColumnTypeSQLSnippet() instead + [$columnTypeSQL, $joinCheckConstraintSQL] = $this->_platform->getColumnTypeSQLSnippets('c', $databaseName); $sql = 'SELECT'; diff --git a/doctrine/dbal/src/Schema/SQLServerSchemaManager.php b/doctrine/dbal/src/Schema/SQLServerSchemaManager.php index 64538e689..acef511ab 100644 --- a/doctrine/dbal/src/Schema/SQLServerSchemaManager.php +++ b/doctrine/dbal/src/Schema/SQLServerSchemaManager.php @@ -133,12 +133,20 @@ protected function _getPortableTableColumnDefinition($tableColumn) switch ($dbType) { case 'nchar': - case 'nvarchar': case 'ntext': // Unicode data requires 2 bytes per character $length /= 2; break; + case 'nvarchar': + if ($length === -1) { + break; + } + + // Unicode data requires 2 bytes per character + $length /= 2; + break; + case 'varchar': // TEXT type is returned as VARCHAR(MAX) with a length of -1 if ($length === -1) {