Skip to content

Commit a6a94cd

Browse files
committed
Merge branch '3.6.x' into 4.0.x
* 3.6.x: Include stability in coverage file key (doctrine#12112) Allow Symfony 8 (doctrine#12110) Run tests with Symfony 8 (doctrine#12102) Improve comment Convert test into 2 unit tests Quote parts of the table name
2 parents c5e5742 + a774ced commit a6a94cd

File tree

7 files changed

+145
-44
lines changed

7 files changed

+145
-44
lines changed

.github/workflows/continuous-integration.yml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,21 +39,32 @@ jobs:
3939
- "pdo_sqlite"
4040
deps:
4141
- "highest"
42+
stability:
43+
- "stable"
4244
include:
4345
- php-version: "8.4"
4446
dbal-version: "4@dev"
4547
extension: "pdo_sqlite"
48+
stability: "stable"
4649
- php-version: "8.4"
4750
dbal-version: "4@dev"
4851
extension: "sqlite3"
52+
stability: "stable"
4953
- php-version: "8.4"
5054
dbal-version: "default"
5155
deps: "lowest"
5256
extension: "pdo_sqlite"
57+
stability: "stable"
5358
- php-version: "8.4"
5459
dbal-version: "default"
5560
deps: "highest"
5661
extension: "pdo_sqlite"
62+
stability: "stable"
63+
- php-version: "8.4"
64+
dbal-version: "default"
65+
deps: "highest"
66+
extension: "sqlite3"
67+
stability: "dev"
5768

5869
steps:
5970
- name: "Checkout"
@@ -69,6 +80,14 @@ jobs:
6980
coverage: "pcov"
7081
ini-values: "zend.assertions=1, apc.enable_cli=1"
7182

83+
- name: "Allow dev dependencies"
84+
run: |
85+
composer config minimum-stability dev
86+
composer remove --no-update --dev phpbench/phpbench phpdocumentor/guides-cli
87+
composer require --no-update symfony/console:^8 symfony/var-exporter:^8 doctrine/dbal:^4.4
88+
composer require --dev --no-update symfony/cache:^8
89+
if: "${{ matrix.stability == 'dev' }}"
90+
7291
- name: "Require specific DBAL version"
7392
run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update"
7493
if: "${{ matrix.dbal-version != 'default' }}"
@@ -92,7 +111,7 @@ jobs:
92111
- name: "Upload coverage file"
93112
uses: "actions/upload-artifact@v4"
94113
with:
95-
name: "phpunit-${{ matrix.extension }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-${{ matrix.deps }}-coverage"
114+
name: "phpunit-${{ matrix.extension }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-${{ matrix.deps }}-${{ matrix.stability }}-coverage"
96115
path: "coverage*.xml"
97116

98117

composer.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"doctrine/lexer": "^3",
3434
"doctrine/persistence": "^4",
3535
"psr/cache": "^1 || ^2 || ^3",
36-
"symfony/console": "^5.4 || ^6.0 || ^7.0"
36+
"symfony/console": "^5.4 || ^6.0 || ^7.0 || ^8.0"
3737
},
3838
"require-dev": {
3939
"doctrine/coding-standard": "^13.0",
@@ -45,8 +45,8 @@
4545
"phpunit/phpunit": "^10.4.0",
4646
"psr/log": "^1 || ^2 || ^3",
4747
"squizlabs/php_codesniffer": "3.12.0",
48-
"symfony/cache": "^5.4 || ^6.2 || ^7.0",
49-
"symfony/var-exporter": "^6.3.9 || ^7.0"
48+
"symfony/cache": "^5.4 || ^6.2 || ^7.0 || ^8.0",
49+
"symfony/var-exporter": "^6.3.9 || ^7.0 || ^8.0"
5050
},
5151
"suggest": {
5252
"ext-dom": "Provides support for XSD validation for XML mapping files",

src/Mapping/ClassMetadata.php

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -396,13 +396,9 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
396396
public DiscriminatorColumnMapping|null $discriminatorColumn = null;
397397

398398
/**
399-
* READ-ONLY: The primary table definition. The definition is an array with the
400-
* following entries:
399+
* READ-ONLY: The primary table definition.
401400
*
402-
* name => <tableName>
403-
* schema => <schemaName>
404-
* indexes => array
405-
* uniqueConstraints => array
401+
* "quoted" indicates whether the table name is quoted (with backticks) or not
406402
*
407403
* @var mixed[]
408404
* @phpstan-var array{

src/Mapping/DefaultQuoteStrategy.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@
1010
use function array_map;
1111
use function array_merge;
1212
use function assert;
13+
use function explode;
14+
use function implode;
1315
use function is_numeric;
1416
use function preg_replace;
17+
use function sprintf;
1518
use function substr;
1619

1720
/**
@@ -38,7 +41,13 @@ public function getTableName(ClassMetadata $class, AbstractPlatform $platform):
3841
$tableName = $class->table['name'];
3942

4043
if (! empty($class->table['schema'])) {
41-
$tableName = $class->table['schema'] . '.' . $class->table['name'];
44+
return isset($class->table['quoted'])
45+
? sprintf(
46+
'%s.%s',
47+
$platform->quoteSingleIdentifier($class->table['schema']),
48+
$platform->quoteSingleIdentifier($tableName),
49+
)
50+
: $class->table['schema'] . '.' . $class->table['name'];
4251
}
4352

4453
return isset($class->table['quoted'])
@@ -52,7 +61,10 @@ public function getTableName(ClassMetadata $class, AbstractPlatform $platform):
5261
public function getSequenceName(array $definition, ClassMetadata $class, AbstractPlatform $platform): string
5362
{
5463
return isset($definition['quoted'])
55-
? $platform->quoteSingleIdentifier($definition['sequenceName'])
64+
? implode('.', array_map(
65+
static fn (string $part) => $platform->quoteSingleIdentifier($part),
66+
explode('.', $definition['sequenceName']),
67+
))
5668
: $definition['sequenceName'];
5769
}
5870

tests/Tests/ORM/Functional/Ticket/DDC2825Test.php

Lines changed: 16 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
use PHPUnit\Framework\Attributes\DataProvider;
1212
use PHPUnit\Framework\Attributes\Group;
1313

14-
use function sprintf;
15-
1614
/**
1715
* This class makes tests on the correct use of a database schema when entities are stored
1816
*/
@@ -30,28 +28,7 @@ protected function setUp(): void
3028
}
3129
}
3230

33-
#[DataProvider('getTestedClasses')]
34-
public function testClassSchemaMappingsValidity(string $className, string $expectedSchemaName, string $expectedTableName): void
35-
{
36-
$classMetadata = $this->_em->getClassMetadata($className);
37-
$platform = $this->_em->getConnection()->getDatabasePlatform();
38-
$quotedTableName = $this->_em->getConfiguration()->getQuoteStrategy()->getTableName($classMetadata, $platform);
39-
40-
// Check if table name and schema properties are defined in the class metadata
41-
self::assertEquals($expectedTableName, $classMetadata->table['name']);
42-
self::assertEquals($expectedSchemaName, $classMetadata->table['schema']);
43-
44-
$fullTableName = sprintf('%s.%s', $expectedSchemaName, $expectedTableName);
45-
46-
self::assertEquals($fullTableName, $quotedTableName);
47-
48-
// Checks sequence name validity
49-
self::assertEquals(
50-
$fullTableName . '_' . $classMetadata->getSingleIdentifierColumnName() . '_seq',
51-
$classMetadata->getSequenceName($platform),
52-
);
53-
}
54-
31+
/** @param class-string $className */
5532
#[DataProvider('getTestedClasses')]
5633
public function testPersistenceOfEntityWithSchemaMapping(string $className): void
5734
{
@@ -64,17 +41,14 @@ public function testPersistenceOfEntityWithSchemaMapping(string $className): voi
6441
self::assertCount(1, $this->_em->getRepository($className)->findAll());
6542
}
6643

67-
/**
68-
* Data provider
69-
*
70-
* @return string[][]
71-
*/
44+
/** @return list<array{class-string}> */
7245
public static function getTestedClasses(): array
7346
{
7447
return [
75-
[ExplicitSchemaAndTable::class, 'explicit_schema', 'explicit_table'],
76-
[SchemaAndTableInTableName::class, 'implicit_schema', 'implicit_table'],
77-
[DDC2825ClassWithImplicitlyDefinedSchemaAndQuotedTableName::class, 'myschema', 'order'],
48+
[ExplicitSchemaAndTable::class],
49+
[SchemaAndTableInTableName::class],
50+
[DDC2825ClassWithImplicitlyDefinedSchemaAndQuotedTableName::class],
51+
[File::class],
7852
];
7953
}
8054
}
@@ -89,3 +63,13 @@ class DDC2825ClassWithImplicitlyDefinedSchemaAndQuotedTableName
8963
#[ORM\Column(type: 'integer')]
9064
public $id;
9165
}
66+
67+
#[ORM\Entity]
68+
#[ORM\Table(name: '`file`', schema: 'yourschema')]
69+
class File
70+
{
71+
#[ORM\Id]
72+
#[ORM\Column]
73+
#[ORM\GeneratedValue]
74+
public int $id;
75+
}

tests/Tests/ORM/Mapping/ClassMetadataTest.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Doctrine\Tests\ORM\Mapping;
66

77
use ArrayObject;
8+
use Doctrine\DBAL\Platforms\AbstractPlatform;
89
use Doctrine\DBAL\Types\Types;
910
use Doctrine\Deprecations\PHPUnit\VerifyDeprecations;
1011
use Doctrine\ORM\Events;
@@ -50,6 +51,7 @@
5051
use Doctrine\Tests\OrmTestCase;
5152
use DoctrineGlobalArticle;
5253
use LogicException;
54+
use PHPUnit\Framework\Attributes\DataProvider;
5355
use PHPUnit\Framework\Attributes\Group as TestGroup;
5456
use PHPUnit\Framework\Attributes\WithoutErrorHandler;
5557
use ReflectionClass;
@@ -974,6 +976,47 @@ public function testQuotedSequenceName(): void
974976
);
975977
}
976978

979+
#[DataProvider('fullTableNameProvider')]
980+
public function testGetSequenceName(
981+
string $expectedSequenceName,
982+
string $fullTableName,
983+
): void {
984+
$cm = new ClassMetadata(self::class);
985+
$cm->setIdentifier(['id']);
986+
$cm->setPrimaryTable(['name' => $fullTableName]);
987+
988+
$platform = $this->createStub(AbstractPlatform::class);
989+
990+
self::assertSame(
991+
$expectedSequenceName,
992+
$cm->getSequenceName($platform),
993+
);
994+
}
995+
996+
/** @return iterable<string, array{string, string}> */
997+
public static function fullTableNameProvider(): iterable
998+
{
999+
yield 'quoted table name with schema' => [
1000+
'custom.reserved_id_seq',
1001+
'custom.`reserved`',
1002+
];
1003+
1004+
yield 'unquoted table name with schema' => [
1005+
'custom.non_reserved_id_seq',
1006+
'custom.non_reserved',
1007+
];
1008+
1009+
yield 'quoted table name without schema' => [
1010+
'reserved_id_seq',
1011+
'`reserved`',
1012+
];
1013+
1014+
yield 'unquoted table name without schema' => [
1015+
'non_reserved_id_seq',
1016+
'non_reserved',
1017+
];
1018+
}
1019+
9771020
#[TestGroup('DDC-2700')]
9781021
public function testIsIdentifierMappedSuperClass(): void
9791022
{

tests/Tests/ORM/Mapping/DefaultQuoteStrategyTest.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66

77
use Doctrine\DBAL\Platforms\AbstractPlatform;
88
use Doctrine\DBAL\Schema\Name\UnquotedIdentifierFolding;
9+
use Doctrine\ORM\Mapping\ClassMetadata;
910
use Doctrine\ORM\Mapping\DefaultQuoteStrategy;
1011
use Doctrine\Tests\Models\NonPublicSchemaJoins\User as NonPublicSchemaUser;
1112
use Doctrine\Tests\OrmTestCase;
13+
use PHPUnit\Framework\Attributes\DataProvider;
1214
use PHPUnit\Framework\Attributes\Group;
1315

1416
use function assert;
1517
use function enum_exists;
18+
use function sprintf;
1619

1720
/**
1821
* Doctrine\Tests\ORM\Mapping\DefaultQuoteStrategyTest
@@ -34,4 +37,48 @@ public function testGetJoinTableName(): void
3437
$strategy->getJoinTableName($metadata->associationMappings['readers'], $metadata, $platform),
3538
);
3639
}
40+
41+
#[DataProvider('fullTableNameProvider')]
42+
public function testGetTableName(string $expectedFullTableName, string $tableName): void
43+
{
44+
$classMetadata = new ClassMetadata(self::class);
45+
$classMetadata->setPrimaryTable(['name' => $tableName]);
46+
47+
$platform = $this->createStub(AbstractPlatform::class);
48+
$platform->method('quoteSingleIdentifier')
49+
->willReturnCallback(
50+
static fn (string $identifier): string => sprintf('✌️%s✌️', $identifier),
51+
);
52+
53+
$quotedTableName = (new DefaultQuoteStrategy())->getTableName(
54+
$classMetadata,
55+
$platform,
56+
);
57+
58+
self::assertSame($expectedFullTableName, $quotedTableName);
59+
}
60+
61+
/** @return iterable<string, array{string, string}> */
62+
public static function fullTableNameProvider(): iterable
63+
{
64+
yield 'quoted table name with schema' => [
65+
'✌️custom✌️.✌️reserved✌️',
66+
'custom.`reserved`',
67+
];
68+
69+
yield 'unquoted table name with schema' => [
70+
'custom.non_reserved',
71+
'custom.non_reserved',
72+
];
73+
74+
yield 'quoted table name without schema' => [
75+
'✌️reserved✌️',
76+
'`reserved`',
77+
];
78+
79+
yield 'unquoted table name without schema' => [
80+
'non_reserved',
81+
'non_reserved',
82+
];
83+
}
3784
}

0 commit comments

Comments
 (0)