Skip to content

Commit

Permalink
Merge branch '4.3.x' into 5.0.x
Browse files Browse the repository at this point in the history
  • Loading branch information
morozov committed Dec 26, 2024
2 parents 90e0f35 + 85765ed commit d3fcbcf
Show file tree
Hide file tree
Showing 11 changed files with 153 additions and 34 deletions.
21 changes: 21 additions & 0 deletions .github/workflows/website-schema.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

name: "Website config validation"

on:
pull_request:
branches:
- "*.x"
paths:
- ".doctrine-project.json"
- ".github/workflows/website-schema.yml"
push:
branches:
- "*.x"
paths:
- ".doctrine-project.json"
- ".github/workflows/website-schema.yml"

jobs:
json-validate:
name: "Validate JSON schema"
uses: "doctrine/.github/.github/workflows/[email protected]"
3 changes: 2 additions & 1 deletion UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ The `Sequence::isAutoIncrementsFor()` method has been deprecated.

## Deprecated using invalid database object names

Using the following objects with an empty name is deprecated: `Column`, `View`, `Sequence`, `Identifier`.
Using the following objects with an empty name is deprecated: `Table`, `Column`, `Index`, `View`, `Sequence`,
`Identifier`.

Using the following objects with a qualified name is deprecated: `Column`, `ForeignKeyConstraint`, `Index`, `Schema`,
`UniqueConstraint`. If the object name contains a dot, the name should be quoted.
Expand Down
6 changes: 3 additions & 3 deletions src/Platforms/AbstractMySQLPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -230,21 +230,21 @@ protected function _getCreateTableSQL(string $name, array $columns, array $optio
{
$queryFields = $this->getColumnDeclarationListSQL($columns);

if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
if (! empty($options['uniqueConstraints'])) {
foreach ($options['uniqueConstraints'] as $definition) {
$queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($definition);
}
}

// add all indexes
if (isset($options['indexes']) && ! empty($options['indexes'])) {
if (! empty($options['indexes'])) {
foreach ($options['indexes'] as $definition) {
$queryFields .= ', ' . $this->getIndexDeclarationSQL($definition);
}
}

// attach all primary keys
if (isset($options['primary']) && ! empty($options['primary'])) {
if (! empty($options['primary'])) {
$keyColumns = array_unique(array_values($options['primary']));
$queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')';
}
Expand Down
22 changes: 14 additions & 8 deletions src/Platforms/AbstractPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,7 @@ private function buildCreateTableSQL(Table $table, bool $createForeignKeys): arr

foreach ($table->getIndexes() as $index) {
if (! $index->isPrimary()) {
$options['indexes'][$index->getQuotedName($this)] = $index;
$options['indexes'][] = $index;

continue;
}
Expand All @@ -819,7 +819,7 @@ private function buildCreateTableSQL(Table $table, bool $createForeignKeys): arr
}

foreach ($table->getUniqueConstraints() as $uniqueConstraint) {
$options['uniqueConstraints'][$uniqueConstraint->getQuotedName($this)] = $uniqueConstraint;
$options['uniqueConstraints'][] = $uniqueConstraint;
}

if ($createForeignKeys) {
Expand Down Expand Up @@ -961,17 +961,17 @@ protected function _getCreateTableSQL(string $name, array $columns, array $optio
{
$columnListSql = $this->getColumnDeclarationListSQL($columns);

if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
if (! empty($options['uniqueConstraints'])) {
foreach ($options['uniqueConstraints'] as $definition) {
$columnListSql .= ', ' . $this->getUniqueConstraintDeclarationSQL($definition);
}
}

if (isset($options['primary']) && ! empty($options['primary'])) {
if (! empty($options['primary'])) {
$columnListSql .= ', PRIMARY KEY(' . implode(', ', array_unique(array_values($options['primary']))) . ')';
}

if (isset($options['indexes']) && ! empty($options['indexes'])) {
if (! empty($options['indexes'])) {
foreach ($options['indexes'] as $definition) {
$columnListSql .= ', ' . $this->getIndexDeclarationSQL($definition);
}
Expand Down Expand Up @@ -1147,8 +1147,13 @@ public function getCreateSchemaSQL(string $schemaName): string
*/
public function getCreateUniqueConstraintSQL(UniqueConstraint $constraint, string $tableName): string
{
return 'ALTER TABLE ' . $tableName . ' ADD CONSTRAINT ' . $constraint->getQuotedName($this) . ' UNIQUE'
. ' (' . implode(', ', $constraint->getQuotedColumns($this)) . ')';
$sql = 'ALTER TABLE ' . $tableName . ' ADD';

if ($constraint->getName() !== '') {
$sql .= ' CONSTRAINT ' . $constraint->getQuotedName($this);
}

return $sql . ' UNIQUE (' . implode(', ', $constraint->getQuotedColumns($this)) . ')';
}

/**
Expand Down Expand Up @@ -1491,9 +1496,10 @@ public function getUniqueConstraintDeclarationSQL(UniqueConstraint $constraint):
throw new InvalidArgumentException('Incomplete definition. "columns" required.');
}

$chunks = ['CONSTRAINT'];
$chunks = [];

if ($constraint->getName() !== '') {
$chunks[] = 'CONSTRAINT';
$chunks[] = $constraint->getQuotedName($this);
}

Expand Down
4 changes: 2 additions & 2 deletions src/Platforms/PostgreSQLPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ protected function _getCreateTableSQL(string $name, array $columns, array $optio
{
$queryFields = $this->getColumnDeclarationListSQL($columns);

if (isset($options['primary']) && ! empty($options['primary'])) {
if (! empty($options['primary'])) {
$keyColumns = array_unique(array_values($options['primary']));
$queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')';
}
Expand All @@ -390,7 +390,7 @@ protected function _getCreateTableSQL(string $name, array $columns, array $optio

$sql = [$query];

if (isset($options['indexes']) && ! empty($options['indexes'])) {
if (! empty($options['indexes'])) {
foreach ($options['indexes'] as $index) {
$sql[] = $this->getCreateIndexSQL($index, $name);
}
Expand Down
6 changes: 3 additions & 3 deletions src/Platforms/SQLServerPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,13 +204,13 @@ protected function _getCreateTableSQL(string $name, array $columns, array $optio

$columnListSql = $this->getColumnDeclarationListSQL($columns);

if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
if (! empty($options['uniqueConstraints'])) {
foreach ($options['uniqueConstraints'] as $definition) {
$columnListSql .= ', ' . $this->getUniqueConstraintDeclarationSQL($definition);
}
}

if (isset($options['primary']) && ! empty($options['primary'])) {
if (! empty($options['primary'])) {
$flags = '';
if (isset($options['primary_index']) && $options['primary_index']->hasFlag('nonclustered')) {
$flags = ' NONCLUSTERED';
Expand All @@ -231,7 +231,7 @@ protected function _getCreateTableSQL(string $name, array $columns, array $optio

$sql = [$query];

if (isset($options['indexes']) && ! empty($options['indexes'])) {
if (! empty($options['indexes'])) {
foreach ($options['indexes'] as $index) {
$sql[] = $this->getCreateIndexSQL($index, $name);
}
Expand Down
6 changes: 3 additions & 3 deletions src/Platforms/SQLitePlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ protected function _getCreateTableSQL(string $name, array $columns, array $optio
{
$queryFields = $this->getColumnDeclarationListSQL($columns);

if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
if (! empty($options['uniqueConstraints'])) {
foreach ($options['uniqueConstraints'] as $definition) {
$queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($definition);
}
Expand All @@ -296,13 +296,13 @@ protected function _getCreateTableSQL(string $name, array $columns, array $optio
return $query;
}

if (isset($options['indexes']) && ! empty($options['indexes'])) {
if (! empty($options['indexes'])) {
foreach ($options['indexes'] as $indexDef) {
$query[] = $this->getCreateIndexSQL($indexDef, $name);
}
}

if (isset($options['unique']) && ! empty($options['unique'])) {
if (! empty($options['unique'])) {
foreach ($options['unique'] as $indexDef) {
$query[] = $this->getCreateIndexSQL($indexDef, $name);
}
Expand Down
6 changes: 3 additions & 3 deletions src/Schema/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
use function count;
use function strtolower;

/** @extends AbstractOptionallyNamedObject<UnqualifiedName> */
class Index extends AbstractOptionallyNamedObject
/** @extends AbstractNamedObject<UnqualifiedName> */
class Index extends AbstractNamedObject
{
/**
* Asset identifier instances of the column names the index is associated with.
Expand Down Expand Up @@ -51,7 +51,7 @@ public function __construct(
array $flags = [],
private readonly array $options = [],
) {
parent::__construct($name);
parent::__construct($name ?? '');

$this->_isUnique = $isUnique || $isPrimary;
$this->_isPrimary = $isPrimary;
Expand Down
49 changes: 49 additions & 0 deletions tests/Functional/Schema/ForeignKeyConstraintTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Tests\Functional\Schema;

use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Tests\FunctionalTestCase;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\Types;

final class ForeignKeyConstraintTest extends FunctionalTestCase
{
public function testUnnamedForeignKeyConstraint(): void
{
$this->dropTableIfExists('users');
$this->dropTableIfExists('roles');
$this->dropTableIfExists('teams');

$roles = new Table('roles');
$roles->addColumn('id', Types::INTEGER);
$roles->setPrimaryKey(['id']);

$teams = new Table('teams');
$teams->addColumn('id', Types::INTEGER);
$teams->setPrimaryKey(['id']);

$users = new Table('users', [
new Column('id', Type::getType(Types::INTEGER)),
new Column('role_id', Type::getType(Types::INTEGER)),
new Column('team_id', Type::getType(Types::INTEGER)),
], [], [], [
new ForeignKeyConstraint(['role_id'], 'roles', ['id']),
new ForeignKeyConstraint(['team_id'], 'teams', ['id']),
]);
$users->setPrimaryKey(['id']);

$sm = $this->connection->createSchemaManager();
$sm->createTable($roles);
$sm->createTable($teams);
$sm->createTable($users);

$table = $sm->introspectTable('users');

self::assertCount(2, $table->getForeignKeys());
}
}
36 changes: 36 additions & 0 deletions tests/Functional/Schema/UniqueConstraintTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Tests\Functional\Schema;

use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\UniqueConstraint;
use Doctrine\DBAL\Tests\FunctionalTestCase;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\Types;

final class UniqueConstraintTest extends FunctionalTestCase
{
public function testUnnamedUniqueConstraint(): void
{
$this->dropTableIfExists('users');

$users = new Table('users', [
new Column('id', Type::getType(Types::INTEGER)),
new Column('username', Type::getType(Types::STRING), ['length' => 32]),
new Column('email', Type::getType(Types::STRING), ['length' => 255]),
], [], [
new UniqueConstraint('', ['username']),
new UniqueConstraint('', ['email']),
], []);

$sm = $this->connection->createSchemaManager();
$sm->createTable($users);

// we want to assert that the two empty names don't clash, but introspection of unique constraints is currently
// not supported. for now, we just assert that the table can be created without exceptions.
$this->expectNotToPerformAssertions();
}
}
28 changes: 17 additions & 11 deletions tests/Schema/IndexTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@

namespace Doctrine\DBAL\Tests\Schema;

use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Schema\Exception\InvalidName;
use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Name\Identifier;
use Doctrine\Deprecations\PHPUnit\VerifyDeprecations;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;

class IndexTest extends TestCase
{
use VerifyDeprecations;

/** @param mixed[] $options */
private function createIndex(bool $unique = false, bool $primary = false, array $options = []): Index
{
Expand Down Expand Up @@ -174,21 +177,24 @@ public function testOptions(): void
self::assertSame(['where' => 'name IS NULL'], $idx2->getOptions());
}

/** @throws Exception */
public function testGetNonNullObjectName(): void
public function testEmptyName(): void
{
$index = new Index('idx_user_id', ['user_id']);
$name = $index->getObjectName();
$this->expectException(InvalidName::class);

self::assertNotNull($name);
self::assertEquals(Identifier::unquoted('idx_user_id'), $name->getIdentifier());
new Index(null, ['user_id']);
}

/** @throws Exception */
public function testGetNullObjectName(): void
public function testQualifiedName(): void
{
$index = new Index(null, ['user_id']);
$this->expectException(InvalidName::class);

new Index('auth.idx_user_id', ['user_id']);
}

public function testGetObjectName(): void
{
$index = new Index('idx_user_id', ['user_id']);

self::assertNull($index->getObjectName());
self::assertEquals(Identifier::unquoted('idx_user_id'), $index->getObjectName()->getIdentifier());
}
}

0 comments on commit d3fcbcf

Please sign in to comment.