From 0e26e3ed503e773b05e445557b80508538d9b215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 5 May 2024 22:39:45 +0200 Subject: [PATCH 1/7] Setup Dependabot Targeting 2.19.x, since we want the updates to bubble up. Since Dependabot has had no effect on doctrine/dbal yet, I suppose that means that "dependabot.yml" must be present on the default branch. --- .github/dependabot.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..c704d7d05b --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,9 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + labels: + - "CI" + target-branch: "2.19.x" From e6bb4ef20e2b0e8bdc97cdbc473d1f016cee437a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 5 May 2024 22:43:51 +0200 Subject: [PATCH 2/7] Upgrade codecov/codecov-action --- .github/workflows/continuous-integration.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index ab98943cc3..1639b09cd9 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -377,6 +377,8 @@ jobs: path: "reports" - name: "Upload to Codecov" - uses: "codecov/codecov-action@v3" + uses: "codecov/codecov-action@v4" with: directory: reports + env: + CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}" From f26b3b9cf9af9c0866a0916d35d0ee1c5372a264 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 May 2024 21:17:24 +0000 Subject: [PATCH 3/7] Bump doctrine/.github from 3.0.0 to 5.0.1 Bumps [doctrine/.github](https://github.com/doctrine/.github) from 3.0.0 to 5.0.1. - [Release notes](https://github.com/doctrine/.github/releases) - [Commits](https://github.com/doctrine/.github/compare/3.0.0...5.0.1) --- updated-dependencies: - dependency-name: doctrine/.github dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/coding-standards.yml | 2 +- .github/workflows/release-on-milestone-closed.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index ac2788b39a..659da17bac 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -24,4 +24,4 @@ on: jobs: coding-standards: - uses: "doctrine/.github/.github/workflows/coding-standards.yml@3.0.0" + uses: "doctrine/.github/.github/workflows/coding-standards.yml@5.0.1" diff --git a/.github/workflows/release-on-milestone-closed.yml b/.github/workflows/release-on-milestone-closed.yml index d46dc4c36b..89d4fe8bf1 100644 --- a/.github/workflows/release-on-milestone-closed.yml +++ b/.github/workflows/release-on-milestone-closed.yml @@ -7,7 +7,7 @@ on: jobs: release: - uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@4.0.0" + uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@5.0.1" secrets: GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }} GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }} From 029ca611f0d06c9eccacc2874d3b138c005fb2ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 5 May 2024 23:38:41 +0200 Subject: [PATCH 4/7] Use ramsey/composer-install in PHPBench workflow (#11444) It will handle caching for us. --- .github/workflows/phpbench.yml | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/.github/workflows/phpbench.yml b/.github/workflows/phpbench.yml index d98e7fa215..2a09ec3b18 100644 --- a/.github/workflows/phpbench.yml +++ b/.github/workflows/phpbench.yml @@ -47,15 +47,8 @@ jobs: coverage: "pcov" ini-values: "zend.assertions=1, apc.enable_cli=1" - - name: "Cache dependencies installed with composer" - uses: "actions/cache@v3" - with: - path: "~/.composer/cache" - key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}" - restore-keys: "php-${{ matrix.php-version }}-composer-locked-" - - - name: "Install dependencies with composer" - run: "composer update --no-interaction --no-progress" + - name: "Install dependencies with Composer" + uses: "ramsey/composer-install@v3" - name: "Run PHPBench" run: "vendor/bin/phpbench run --report=default" From c5291b4de8b3d256433c9f247e8b47baa690ac9e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 May 2024 23:47:43 +0200 Subject: [PATCH 5/7] Bump ramsey/composer-install from 2 to 3 (#11442) Bumps [ramsey/composer-install](https://github.com/ramsey/composer-install) from 2 to 3. - [Release notes](https://github.com/ramsey/composer-install/releases) - [Commits](https://github.com/ramsey/composer-install/compare/v2...v3) --- updated-dependencies: - dependency-name: ramsey/composer-install dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/continuous-integration.yml | 10 +++++----- .github/workflows/documentation.yml | 2 +- .github/workflows/static-analysis.yml | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 1639b09cd9..47453fdae5 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -80,7 +80,7 @@ jobs: if: "${{ matrix.dbal-version != 'default' }}" - name: "Install dependencies with Composer" - uses: "ramsey/composer-install@v2" + uses: "ramsey/composer-install@v3" with: composer-options: "--ignore-platform-req=php+" @@ -162,7 +162,7 @@ jobs: if: "${{ matrix.dbal-version != 'default' }}" - name: "Install dependencies with Composer" - uses: "ramsey/composer-install@v2" + uses: "ramsey/composer-install@v3" with: composer-options: "--ignore-platform-req=php+" @@ -232,7 +232,7 @@ jobs: extensions: "${{ matrix.extension }}" - name: "Install dependencies with Composer" - uses: "ramsey/composer-install@v2" + uses: "ramsey/composer-install@v3" with: composer-options: "--ignore-platform-req=php+" @@ -302,7 +302,7 @@ jobs: if: "${{ matrix.dbal-version != 'default' }}" - name: "Install dependencies with Composer" - uses: "ramsey/composer-install@v2" + uses: "ramsey/composer-install@v3" with: composer-options: "--ignore-platform-req=php+" @@ -348,7 +348,7 @@ jobs: ini-values: "zend.assertions=1, apc.enable_cli=1" - name: "Install dependencies with Composer" - uses: "ramsey/composer-install@v2" + uses: "ramsey/composer-install@v3" with: dependency-versions: "${{ matrix.deps }}" diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index ef8053a211..65cbad613b 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -36,7 +36,7 @@ jobs: run: "composer require --dev phpdocumentor/guides-cli --no-update" - name: "Install dependencies with Composer" - uses: "ramsey/composer-install@v2" + uses: "ramsey/composer-install@v3" with: dependency-versions: "highest" diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index a8765e2329..6ed391c70b 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -58,7 +58,7 @@ jobs: run: "composer require doctrine/persistence ^$([ ${{ matrix.persistence-version }} = default ] && echo '3.1' || echo ${{ matrix.persistence-version }}) --no-update" - name: "Install dependencies with Composer" - uses: "ramsey/composer-install@v2" + uses: "ramsey/composer-install@v3" with: dependency-versions: "highest" @@ -95,7 +95,7 @@ jobs: run: "composer require doctrine/persistence ^3.1 --no-update" - name: "Install dependencies with Composer" - uses: "ramsey/composer-install@v2" + uses: "ramsey/composer-install@v3" with: dependency-versions: "highest" From e83d8a80baa917a2018efa93f5fc70f4529c8a7e Mon Sep 17 00:00:00 2001 From: Alexey Prohorov Date: Wed, 15 May 2024 10:42:04 +0300 Subject: [PATCH 6/7] Using an integer as discriminator value with ORM v3 This fixes a bug that occurred when configuring integers as discriminator values. Doctrine throws a type error whenever the application generates queries. --- src/Query/SqlWalker.php | 9 +- .../ORM/Functional/Ticket/GH11341Test.php | 131 ++++++++++++++++++ 2 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 tests/Tests/ORM/Functional/Ticket/GH11341Test.php diff --git a/src/Query/SqlWalker.php b/src/Query/SqlWalker.php index 018c2455e4..7fdc9a6f9c 100644 --- a/src/Query/SqlWalker.php +++ b/src/Query/SqlWalker.php @@ -30,6 +30,7 @@ use function implode; use function is_array; use function is_float; +use function is_int; use function is_numeric; use function is_string; use function preg_match; @@ -384,7 +385,9 @@ private function generateDiscriminatorColumnConditionSQL(array $dqlAliases): str $values = []; if ($class->discriminatorValue !== null) { // discriminators can be 0 - $values[] = $conn->quote($class->discriminatorValue); + $values[] = $class->getDiscriminatorColumn()->type === 'integer' && is_int($class->discriminatorValue) + ? $class->discriminatorValue + : $conn->quote((string) $class->discriminatorValue); } foreach ($class->subClasses as $subclassName) { @@ -396,7 +399,9 @@ private function generateDiscriminatorColumnConditionSQL(array $dqlAliases): str continue; } - $values[] = $conn->quote((string) $subclassMetadata->discriminatorValue); + $values[] = $subclassMetadata->getDiscriminatorColumn()->type === 'integer' && is_int($subclassMetadata->discriminatorValue) + ? $subclassMetadata->discriminatorValue + : $conn->quote((string) $subclassMetadata->discriminatorValue); } if ($values !== []) { diff --git a/tests/Tests/ORM/Functional/Ticket/GH11341Test.php b/tests/Tests/ORM/Functional/Ticket/GH11341Test.php new file mode 100644 index 0000000000..16853418cc --- /dev/null +++ b/tests/Tests/ORM/Functional/Ticket/GH11341Test.php @@ -0,0 +1,131 @@ +setUpEntitySchema([ + IntegerBaseClass::class, + IntegerFooEntity::class, + IntegerBarEntity::class, + StringAsIntBaseClass::class, + StringAsIntFooEntity::class, + StringAsIntBarEntity::class, + StringBaseClass::class, + StringFooEntity::class, + StringBarEntity::class, + ]); + } + + public static function dqlStatements(): Generator + { + yield ['SELECT e FROM ' . IntegerBaseClass::class . ' e', '/WHERE [a-z]0_.type IN \(1, 2\)$/']; + yield ['SELECT e FROM ' . IntegerFooEntity::class . ' e', '/WHERE [a-z]0_.type IN \(1\)$/']; + yield ['SELECT e FROM ' . IntegerBarEntity::class . ' e', '/WHERE [a-z]0_.type IN \(2\)$/']; + yield ['SELECT e FROM ' . StringAsIntBaseClass::class . ' e', '/WHERE [a-z]0_.type IN \(\'1\', \'2\'\)$/']; + yield ['SELECT e FROM ' . StringAsIntFooEntity::class . ' e', '/WHERE [a-z]0_.type IN \(\'1\'\)$/']; + yield ['SELECT e FROM ' . StringAsIntBarEntity::class . ' e', '/WHERE [a-z]0_.type IN \(\'2\'\)$/']; + yield ['SELECT e FROM ' . StringBaseClass::class . ' e', '/WHERE [a-z]0_.type IN \(\'1\', \'2\'\)$/']; + yield ['SELECT e FROM ' . StringFooEntity::class . ' e', '/WHERE [a-z]0_.type IN \(\'1\'\)$/']; + yield ['SELECT e FROM ' . StringBarEntity::class . ' e', '/WHERE [a-z]0_.type IN \(\'2\'\)$/']; + } + + #[DataProvider('dqlStatements')] + public function testDiscriminatorValue(string $dql, string $expectedDiscriminatorValues): void + { + $query = $this->_em->createQuery($dql); + $sql = $query->getSQL(); + + self::assertMatchesRegularExpression($expectedDiscriminatorValues, $sql); + } +} + +#[ORM\Entity] +#[ORM\Table(name: 'integer_discriminator')] +#[ORM\InheritanceType('SINGLE_TABLE')] +#[ORM\DiscriminatorColumn(name: 'type', type: 'integer')] +#[ORM\DiscriminatorMap([ + 1 => IntegerFooEntity::class, + 2 => IntegerBarEntity::class, +])] +class IntegerBaseClass +{ + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'IDENTITY')] + #[ORM\Column(type: 'integer')] + private int|null $id = null; +} + +#[ORM\Entity] +class IntegerFooEntity extends IntegerBaseClass +{ +} + +#[ORM\Entity] +class IntegerBarEntity extends IntegerBaseClass +{ +} + +#[ORM\Entity] +#[ORM\Table(name: 'string_as_int_discriminator')] +#[ORM\InheritanceType('SINGLE_TABLE')] +#[ORM\DiscriminatorColumn(name: 'type', type: 'string')] +#[ORM\DiscriminatorMap([ + 1 => StringAsIntFooEntity::class, + 2 => StringAsIntBarEntity::class, +])] +class StringAsIntBaseClass +{ + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'IDENTITY')] + #[ORM\Column(type: 'integer')] + private int|null $id = null; +} + +#[ORM\Entity] +class StringAsIntFooEntity extends StringAsIntBaseClass +{ +} + +#[ORM\Entity] +class StringAsIntBarEntity extends StringAsIntBaseClass +{ +} + + +#[ORM\Entity] +#[ORM\Table(name: 'string_discriminator')] +#[ORM\InheritanceType('SINGLE_TABLE')] +#[ORM\DiscriminatorColumn(name: 'type', type: 'string')] +#[ORM\DiscriminatorMap([ + '1' => StringFooEntity::class, + '2' => StringBarEntity::class, +])] +class StringBaseClass +{ + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'IDENTITY')] + #[ORM\Column(type: 'integer')] + private int|null $id = null; +} + +#[ORM\Entity] +class StringFooEntity extends StringBaseClass +{ +} + +#[ORM\Entity] +class StringBarEntity extends StringBaseClass +{ +} From 2b04cc2e3f7a1ca8a2e8fa4701c3b3d9b5cfc942 Mon Sep 17 00:00:00 2001 From: Alexey Prohorov Date: Thu, 16 May 2024 11:53:29 +0300 Subject: [PATCH 7/7] Using an integer as discriminator value with ORM v3 This fixes a bug that occurred when configuring integers as discriminator values and using DQL instanceOf function in the queries. Doctrine throws a type error whenever the application generates these queries. --- src/Query/SqlWalker.php | 6 +++-- .../ORM/Functional/Ticket/GH11341Test.php | 26 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/Query/SqlWalker.php b/src/Query/SqlWalker.php index 7fdc9a6f9c..004d29e773 100644 --- a/src/Query/SqlWalker.php +++ b/src/Query/SqlWalker.php @@ -2251,8 +2251,10 @@ private function getChildDiscriminatorsFromClassMetadata( $discriminators += HierarchyDiscriminatorResolver::resolveDiscriminatorsForClass($metadata, $this->em); } - foreach (array_keys($discriminators) as $dis) { - $sqlParameterList[] = $this->conn->quote($dis); + foreach (array_keys($discriminators) as $discriminatorValue) { + $sqlParameterList[] = $rootClass->getDiscriminatorColumn()->type === 'integer' && is_int($discriminatorValue) + ? $discriminatorValue + : $this->conn->quote((string) $discriminatorValue); } return '(' . implode(', ', $sqlParameterList) . ')'; diff --git a/tests/Tests/ORM/Functional/Ticket/GH11341Test.php b/tests/Tests/ORM/Functional/Ticket/GH11341Test.php index 16853418cc..5c35dfe86c 100644 --- a/tests/Tests/ORM/Functional/Ticket/GH11341Test.php +++ b/tests/Tests/ORM/Functional/Ticket/GH11341Test.php @@ -49,6 +49,32 @@ public function testDiscriminatorValue(string $dql, string $expectedDiscriminato self::assertMatchesRegularExpression($expectedDiscriminatorValues, $sql); } + + public static function dqlStatementsForInstanceOf(): Generator + { + yield [IntegerBaseClass::class, IntegerFooEntity::class]; + yield [StringBaseClass::class, StringFooEntity::class]; + yield [StringAsIntBaseClass::class, StringAsIntFooEntity::class]; + } + + /** + * @psalm-param class-string $baseClass + * @psalm-param class-string $inheritedClass + */ + #[DataProvider('dqlStatementsForInstanceOf')] + public function testInstanceOf(string $baseClass, string $inheritedClass): void + { + $this->_em->persist(new $inheritedClass()); + $this->_em->flush(); + + $dql = 'SELECT p FROM ' . $baseClass . ' p WHERE p INSTANCE OF ' . $baseClass; + + $query = $this->_em->createQuery($dql); + $result = $query->getResult(); + + self::assertCount(1, $result); + self::assertContainsOnlyInstancesOf($baseClass, $result); + } } #[ORM\Entity]