From c65cc91f5bf47087e58832587113b2327878d647 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Tue, 24 Aug 2021 04:43:02 +0200 Subject: [PATCH] Support for DBAL 3 --- .github/workflows/continuous-integration.yml | 93 +++++++++---------- .github/workflows/static-analysis.yml | 31 ++----- composer.json | 2 +- phpstan-dbal2.neon | 12 +++ phpstan-dbal3.neon | 18 ---- phpstan.neon | 36 +++++-- psalm-baseline.xml | 16 ---- psalm.xml | 34 +++++++ .../Performance/EntityManagerFactory.php | 9 +- .../SimpleInsertPerformanceBench.php | 2 +- 10 files changed, 134 insertions(+), 119 deletions(-) create mode 100644 phpstan-dbal2.neon delete mode 100644 phpstan-dbal3.neon diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index d3130033e1b..d43e8fbe2f8 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -8,56 +8,6 @@ env: fail-fast: true jobs: - phpunit-smoke-check-dbal-3: - name: "Experimental: PHPUnit with SQLite and DBAL 3" - runs-on: "ubuntu-20.04" - continue-on-error: true - - strategy: - matrix: - php-version: - - "8.0" - - steps: - - name: "Checkout" - uses: "actions/checkout@v2" - with: - fetch-depth: 2 - - - name: "Install PHP" - uses: "shivammathur/setup-php@v2" - with: - php-version: "${{ matrix.php-version }}" - extensions: "pdo, pdo_sqlite" - coverage: "pcov" - ini-values: "zend.assertions=1" - - - name: "Require DBAL 3" - run: "composer require doctrine/dbal ^3.0 --no-update" - - - name: "Install dependencies with Composer" - uses: "ramsey/composer-install@v1" - - - name: "Run PHPUnit" - continue-on-error: true - run: "vendor/bin/phpunit -c ci/github/phpunit/sqlite.xml --coverage-clover=coverage-no-cache.xml" - env: - ENABLE_SECOND_LEVEL_CACHE: 0 - - - name: "Run PHPUnit with Second Level Cache" - id: "phpunit-run-slc" - continue-on-error: true - run: "vendor/bin/phpunit -c ci/github/phpunit/sqlite.xml --exclude-group performance,non-cacheable,locking_functional --coverage-clover=coverage-cache.xml" - env: - ENABLE_SECOND_LEVEL_CACHE: 1 - - - name: "Upload coverage file" - uses: "actions/upload-artifact@v2" - if: "steps.phpunit-run-slc.outcome == 'success' && steps.phpunit-run-slc.conclusion == 'success'" - with: - name: "phpunit-sqlite-${{ matrix.php-version }}-dbal3-coverage" - path: "coverage*.xml" - phpunit-smoke-check: name: "PHPUnit with SQLite" runs-on: "ubuntu-20.04" @@ -69,6 +19,11 @@ jobs: - "7.3" - "7.4" - "8.0" + dbal-version: + - "default" + include: + - php-version: "8.0" + dbal-version: "2.13" steps: - name: "Checkout" @@ -84,6 +39,10 @@ jobs: coverage: "pcov" ini-values: "zend.assertions=1" + - name: "Require specific DBAL version" + run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update" + if: "${{ matrix.dbal-version != 'default' }}" + - name: "Install dependencies with Composer" uses: "ramsey/composer-install@v1" @@ -113,9 +72,15 @@ jobs: matrix: php-version: - "7.4" + dbal-version: + - "default" postgres-version: - "9.6" - "13" + include: + - php-version: "8.0" + dbal-version: "2.13" + postgres-version: "13" services: postgres: @@ -142,6 +107,10 @@ jobs: coverage: "pcov" ini-values: "zend.assertions=1" + - name: "Require specific DBAL version" + run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update" + if: "${{ matrix.dbal-version != 'default' }}" + - name: "Install dependencies with Composer" uses: "ramsey/composer-install@v1" @@ -164,11 +133,18 @@ jobs: matrix: php-version: - "7.4" + dbal-version: + - "default" mariadb-version: - "10.5" extension: - "mysqli" - "pdo_mysql" + include: + - php-version: "8.0" + dbal-version: "2.13" + mariadb-version: "10.5" + extension: "pdo_mysql" services: mariadb: @@ -189,6 +165,10 @@ jobs: with: fetch-depth: 2 + - name: "Require specific DBAL version" + run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update" + if: "${{ matrix.dbal-version != 'default' }}" + - name: "Install PHP" uses: "shivammathur/setup-php@v2" with: @@ -219,12 +199,19 @@ jobs: matrix: php-version: - "7.4" + dbal-version: + - "default" mysql-version: - "5.7" - "8.0" extension: - "mysqli" - "pdo_mysql" + include: + - php-version: "8.0" + dbal-version: "2.13" + mysql-version: "8.0" + extension: "pdo_mysql" services: mysql: @@ -252,6 +239,10 @@ jobs: ini-values: "zend.assertions=1" extensions: "${{ matrix.extension }}" + - name: "Require specific DBAL version" + run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update" + if: "${{ matrix.dbal-version != 'default' }}" + - name: "Install dependencies with Composer" uses: "ramsey/composer-install@v1" @@ -271,6 +262,7 @@ jobs: name: "${{ github.job }}-${{ matrix.mysql-version }}-${{ matrix.extension }}-${{ matrix.php-version }}-coverage" path: "coverage*.xml" + phpunit-lower-php-versions: name: "PHPUnit with SQLite" runs-on: "ubuntu-20.04" @@ -303,6 +295,7 @@ jobs: - name: "Run PHPUnit" run: "vendor/bin/phpunit -c ci/github/phpunit/sqlite.xml" + upload_coverage: name: "Upload coverage to Codecov" runs-on: "ubuntu-20.04" diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 01780c3c3ff..7556eac641b 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -13,7 +13,6 @@ jobs: static-analysis-phpstan: name: "Static Analysis with PHPStan" runs-on: "ubuntu-20.04" - continue-on-error: "${{ matrix.status == 'experimental' }}" strategy: fail-fast: false @@ -22,12 +21,7 @@ jobs: - "8.0" dbal-version: - "default" - status: - - "stable" - include: - - dbal-version: "^3.0" - php-version: "8.0" - status: "experimental" + - "2.13" steps: - name: "Checkout code" @@ -39,8 +33,8 @@ jobs: coverage: "none" php-version: "${{ matrix.php-version }}" - - name: "Require DBAL 3" - run: "composer require doctrine/dbal ${{ matrix.dbal-version }} --no-update" + - name: "Require specific DBAL version" + run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update" if: "${{ matrix.dbal-version != 'default' }}" - name: "Install dependencies with Composer" @@ -49,19 +43,16 @@ jobs: dependency-versions: "highest" - name: "Run a static analysis with phpstan/phpstan" - continue-on-error: "${{ matrix.status == 'experimental' }}" run: "vendor/bin/phpstan analyse" if: "${{ matrix.dbal-version == 'default' }}" - name: "Run a static analysis with phpstan/phpstan" - continue-on-error: "${{ matrix.status == 'experimental' }}" - run: "vendor/bin/phpstan analyse -c phpstan-dbal3.neon" - if: "${{ matrix.dbal-version != 'default' }}" + run: "vendor/bin/phpstan analyse -c phpstan-dbal2.neon" + if: "${{ matrix.dbal-version == '2.13' }}" static-analysis-psalm: name: "Static Analysis with Psalm" runs-on: "ubuntu-20.04" - continue-on-error: "${{ matrix.status == 'experimental' }}" strategy: fail-fast: false @@ -70,12 +61,7 @@ jobs: - "8.0" dbal-version: - "default" - status: - - "stable" - include: - - dbal-version: "^3.0" - php-version: "8.0" - status: "experimental" + - "2.13" steps: - name: "Checkout code" @@ -87,8 +73,8 @@ jobs: coverage: "none" php-version: "${{ matrix.php-version }}" - - name: "Require DBAL 3" - run: "composer require doctrine/dbal ${{ matrix.dbal-version }} --no-update" + - name: "Require specific DBAL version" + run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update" if: "${{ matrix.dbal-version != 'default' }}" - name: "Install dependencies with Composer" @@ -97,5 +83,4 @@ jobs: dependency-versions: "highest" - name: "Run a static analysis with vimeo/psalm" - continue-on-error: "${{ matrix.status == 'experimental' }}" run: "vendor/bin/psalm --show-info=false --stats --output-format=github --threads=$(nproc)" diff --git a/composer.json b/composer.json index d80b37332f3..4587058e6cd 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ "doctrine/cache": "^1.12.1 || ^2.1.1", "doctrine/collections": "^1.5", "doctrine/common": "^3.0.3", - "doctrine/dbal": "^2.13.1", + "doctrine/dbal": "^2.13.1 || ^3.1.1", "doctrine/deprecations": "^0.5.3", "doctrine/event-manager": "^1.1", "doctrine/inflector": "^1.4 || ^2.0", diff --git a/phpstan-dbal2.neon b/phpstan-dbal2.neon new file mode 100644 index 00000000000..154fae42d4c --- /dev/null +++ b/phpstan-dbal2.neon @@ -0,0 +1,12 @@ +includes: + - phpstan-baseline.neon + - phpstan-params.neon + +parameters: + ignoreErrors: + # https://github.com/doctrine/collections/pull/282 + - '/Variable \$offset in isset\(\) always exists and is not nullable\./' + # PHPStan doesn't understand our method_exists() safeguards. + - '/Call to an undefined method Doctrine\\DBAL\\Connection::createSchemaManager\(\)\./' + # Class name will change in DBAL 3. + - '/Class Doctrine\\DBAL\\Platforms\\PostgreSqlPlatform referenced with incorrect case: Doctrine\\DBAL\\Platforms\\PostgreSQLPlatform\./' diff --git a/phpstan-dbal3.neon b/phpstan-dbal3.neon deleted file mode 100644 index 75455e9b764..00000000000 --- a/phpstan-dbal3.neon +++ /dev/null @@ -1,18 +0,0 @@ -includes: - - phpstan-baseline.neon - - phpstan-params.neon - -parameters: - ignoreErrors: - # deprecations from doctrine/dbal:3.x - - '/^Call to an undefined method Doctrine\\DBAL\\Platforms\\AbstractPlatform::getGuidExpression\(\).$/' - - # Fallback logic for DBAL 2 - - - message: '/HelperSet constructor expects/' - path: lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php - - - message: '/Application::add\(\) expects Symfony\\Component\\Console\\Command\\Command/' - path: lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php - - - '/^Class Doctrine\\DBAL\\Platforms\\(PostgreSQL|SQLServer|SQLAnywhere)Platform not found\.$/' diff --git a/phpstan.neon b/phpstan.neon index 154fae42d4c..9a52cd39c44 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -4,9 +4,33 @@ includes: parameters: ignoreErrors: - # https://github.com/doctrine/collections/pull/282 - - '/Variable \$offset in isset\(\) always exists and is not nullable\./' - # PHPStan doesn't understand our method_exists() safeguards. - - '/Call to an undefined method Doctrine\\DBAL\\Connection::createSchemaManager\(\)\./' - # Class name will change in DBAL 3. - - '/Class Doctrine\\DBAL\\Platforms\\PostgreSqlPlatform referenced with incorrect case: Doctrine\\DBAL\\Platforms\\PostgreSQLPlatform\./' + # deprecations from doctrine/dbal:3.x + - '/^Call to an undefined method Doctrine\\DBAL\\Platforms\\AbstractPlatform::getGuidExpression\(\).$/' + + # Fallback logic for DBAL 2 + - + message: '/HelperSet constructor expects/' + path: lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php + - + message: '/Application::add\(\) expects Symfony\\Component\\Console\\Command\\Command/' + path: lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php + + - '/^Class Doctrine\\DBAL\\Platforms\\(PostgreSQL|SQLServer|SQLAnywhere)Platform not found\.$/' + + - + message: '/^Call to an undefined method Doctrine\\DBAL\\Platforms\\AbstractPlatform::getSQLResultCasing\(\)\.$/' + path: lib/Doctrine/ORM/Internal/SQLResultCasing.php + - + message: '/^Parameter \$stmt of method .* has invalid typehint type Doctrine\\DBAL\\Driver\\ResultStatement\.$/' + path: lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php + - + message: '/^Class Doctrine\\DBAL\\Driver\\ResultStatement not found\.$/' + path: lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php + - + message: '/^Call to static method ensure\(\) on an unknown class Doctrine\\DBAL\\ForwardCompatibility\\Result\.$/' + path: lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php + + # False positive + - + message: '/^Variable \$offset in isset\(\) always exists and is not nullable\.$/' + path: lib/Doctrine/ORM/PersistentCollection.php diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 98f31904209..0bc779165fb 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -641,11 +641,6 @@ getTableHiLoUpdateNextValSql - - - getGuidExpression - - $vertex->state !== self::VISITED @@ -733,11 +728,6 @@ $class - - - PostgreSQL94Platform - - $element @@ -874,9 +864,6 @@ $driver $evm - - Platforms\PostgreSQL94Platform - $class->cache $class->changeTrackingPolicy @@ -3781,9 +3768,6 @@ - - PostgreSQL94Platform - $query diff --git a/psalm.xml b/psalm.xml index 20eded4727d..ba8ea53e0fb 100644 --- a/psalm.xml +++ b/psalm.xml @@ -29,12 +29,17 @@ + + + + + @@ -43,6 +48,14 @@ + + + + + + + + @@ -55,6 +68,12 @@ + + + + + + @@ -66,8 +85,23 @@ + + + + + + + + + + + + + + + diff --git a/tests/Doctrine/Performance/EntityManagerFactory.php b/tests/Doctrine/Performance/EntityManagerFactory.php index eb0f9a31368..852d3ef1bf2 100644 --- a/tests/Doctrine/Performance/EntityManagerFactory.php +++ b/tests/Doctrine/Performance/EntityManagerFactory.php @@ -5,15 +5,16 @@ namespace Doctrine\Performance; use Doctrine\Common\EventManager; -use Doctrine\DBAL\Cache\ArrayStatement; use Doctrine\DBAL\Cache\QueryCacheProfile; use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Driver\PDOSqlite\Driver; +use Doctrine\DBAL\Driver\PDO\SQLite\Driver; +use Doctrine\DBAL\Result; use Doctrine\ORM\Configuration; use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Proxy\ProxyFactory; use Doctrine\ORM\Tools\SchemaTool; +use Doctrine\Tests\Mocks\DriverResultMock; use function array_map; use function realpath; @@ -63,9 +64,9 @@ public static function makeEntityManagerWithNoResultsConnection(): EntityManager $connection = new class ([], new Driver(), null, new EventManager()) extends Connection { /** {@inheritdoc} */ - public function executeQuery($query, array $params = [], $types = [], ?QueryCacheProfile $qcp = null) + public function executeQuery(string $sql, array $params = [], $types = [], ?QueryCacheProfile $qcp = null): Result { - return new ArrayStatement([]); + return new Result(new DriverResultMock(), $this); } }; diff --git a/tests/Doctrine/Performance/Hydration/SimpleInsertPerformanceBench.php b/tests/Doctrine/Performance/Hydration/SimpleInsertPerformanceBench.php index 15a9f457ac1..4ac02011ce3 100644 --- a/tests/Doctrine/Performance/Hydration/SimpleInsertPerformanceBench.php +++ b/tests/Doctrine/Performance/Hydration/SimpleInsertPerformanceBench.php @@ -53,7 +53,7 @@ public function benchHydration(): void // Yes, this is a lot of overhead, but I have no better solution other than // completely mocking out the DB, which would be silly (query impact is // necessarily part of our benchmarks) - $this->entityManager->getConnection()->executeQuery('DELETE FROM ' . $this->tableName)->execute(); + $this->entityManager->getConnection()->executeStatement('DELETE FROM ' . $this->tableName); foreach ($this->users as $key => $user) { $this->entityManager->persist($user);