diff --git a/UPGRADE.md b/UPGRADE.md
index d0c647e13a7..01ecdec99bd 100644
--- a/UPGRADE.md
+++ b/UPGRADE.md
@@ -1,5 +1,9 @@
# Upgrade to 4.0
+## Remove `DatabaseDriver`
+
+The class `Doctrine\ORM\Mapping\Driver\DatabaseDriver` is removed.
+
## Remove the `NotSupported` exception
The class `Doctrine\ORM\Exception\NotSupported` has been removed without replacement.
diff --git a/psalm-baseline.xml b/psalm-baseline.xml
index 12e6b74dd1f..ef91d9fd3c0 100644
--- a/psalm-baseline.xml
+++ b/psalm-baseline.xml
@@ -295,15 +295,9 @@
-
-
-
-
- reflClass]]>
-
@@ -312,9 +306,6 @@
declaredField]]]>
-
-
-
@@ -436,35 +427,12 @@
* columnDefinition?: string
* }]]>
-
- getReflectionClass()]]>
-
-
- name)]]>
-
-
-
-
-
-
-
-
-
-
- tables[$tableName]]]>
- tables[$tableName]]]>
-
-
-
-
-
-
diff --git a/psalm.xml b/psalm.xml
index d5c3d090ddf..ddb88d51c20 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -78,18 +78,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Mapping/ClassMetadata.php b/src/Mapping/ClassMetadata.php
index a4f620e5083..29988bae8be 100644
--- a/src/Mapping/ClassMetadata.php
+++ b/src/Mapping/ClassMetadata.php
@@ -510,9 +510,9 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
/**
* The ReflectionClass instance of the mapped class.
*
- * @var ReflectionClass|null
+ * @var ReflectionClass
*/
- public ReflectionClass|null $reflClass = null;
+ public ReflectionClass $reflClass;
/**
* Is this entity marked as "read-only"?
@@ -552,6 +552,7 @@ public function __construct(public string $name, NamingStrategy|null $namingStra
$this->namingStrategy = $namingStrategy ?? new DefaultNamingStrategy();
$this->instantiator = new Instantiator();
$this->typedFieldMapper = $typedFieldMapper ?? new DefaultTypedFieldMapper();
+ $this->reflClass = new ReflectionClass($name);
}
/**
@@ -928,12 +929,7 @@ public function validateLifecycleCallbacks(ReflectionService $reflService): void
}
}
- /**
- * {@inheritDoc}
- *
- * Can return null when using static reflection, in violation of the LSP
- */
- public function getReflectionClass(): ReflectionClass|null
+ public function getReflectionClass(): ReflectionClass
{
return $this->reflClass;
}
@@ -1101,8 +1097,7 @@ public function getFieldName(string $columnName): string
*/
private function isTypedProperty(string $name): bool
{
- return isset($this->reflClass)
- && $this->reflClass->hasProperty($name)
+ return $this->reflClass->hasProperty($name)
&& $this->reflClass->getProperty($name)->hasType();
}
@@ -2557,8 +2552,6 @@ public function inlineEmbeddable(string $property, ClassMetadata $embeddable): v
if (! empty($this->embeddedClasses[$property]->columnPrefix)) {
$fieldMapping['columnName'] = $this->embeddedClasses[$property]->columnPrefix . $fieldMapping['columnName'];
} elseif ($this->embeddedClasses[$property]->columnPrefix !== false) {
- assert($this->reflClass !== null);
- assert($embeddable->reflClass !== null);
$fieldMapping['columnName'] = $this->namingStrategy
->embeddedFieldToColumnName(
$property,
diff --git a/src/Mapping/ClassMetadataFactory.php b/src/Mapping/ClassMetadataFactory.php
index 99890e38b70..c69cd1b88f9 100644
--- a/src/Mapping/ClassMetadataFactory.php
+++ b/src/Mapping/ClassMetadataFactory.php
@@ -256,11 +256,6 @@ protected function doLoadMetadata(
*/
protected function validateRuntimeMetadata(ClassMetadata $class, ClassMetadataInterface|null $parent): void
{
- if (! $class->reflClass) {
- // only validate if there is a reflection class instance
- return;
- }
-
$class->validateIdentifier();
$class->validateAssociations();
$class->validateLifecycleCallbacks($this->getReflectionService());
diff --git a/src/Mapping/Driver/AttributeDriver.php b/src/Mapping/Driver/AttributeDriver.php
index 6fed1a24e67..77a391ce2e7 100644
--- a/src/Mapping/Driver/AttributeDriver.php
+++ b/src/Mapping/Driver/AttributeDriver.php
@@ -76,10 +76,7 @@ public function isTransient(string $className): bool
*/
public function loadMetadataForClass(string $className, PersistenceClassMetadata $metadata): void
{
- $reflectionClass = $metadata->getReflectionClass()
- // this happens when running attribute driver in combination with
- // static reflection services. This is not the nicest fix
- ?? new ReflectionClass($metadata->name);
+ $reflectionClass = $metadata->getReflectionClass();
$classAttributes = $this->reader->getClassAttributes($reflectionClass);
diff --git a/src/Mapping/Driver/DatabaseDriver.php b/src/Mapping/Driver/DatabaseDriver.php
deleted file mode 100644
index 19504d832fb..00000000000
--- a/src/Mapping/Driver/DatabaseDriver.php
+++ /dev/null
@@ -1,514 +0,0 @@
-|null */
- private array|null $tables = null;
-
- /** @var array */
- private array $classToTableNames = [];
-
- /** @psalm-var array */
- private array $manyToManyTables = [];
-
- /** @var mixed[] */
- private array $classNamesForTables = [];
-
- /** @var mixed[] */
- private array $fieldNamesForColumns = [];
-
- /**
- * The namespace for the generated entities.
- */
- private string|null $namespace = null;
-
- private Inflector $inflector;
-
- public function __construct(private readonly AbstractSchemaManager $sm)
- {
- $this->inflector = InflectorFactory::create()->build();
- }
-
- /**
- * Set the namespace for the generated entities.
- */
- public function setNamespace(string $namespace): void
- {
- $this->namespace = $namespace;
- }
-
- public function isTransient(string $className): bool
- {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getAllClassNames(): array
- {
- $this->reverseEngineerMappingFromDatabase();
-
- return array_keys($this->classToTableNames);
- }
-
- /**
- * Sets class name for a table.
- */
- public function setClassNameForTable(string $tableName, string $className): void
- {
- $this->classNamesForTables[$tableName] = $className;
- }
-
- /**
- * Sets field name for a column on a specific table.
- */
- public function setFieldNameForColumn(string $tableName, string $columnName, string $fieldName): void
- {
- $this->fieldNamesForColumns[$tableName][$columnName] = $fieldName;
- }
-
- /**
- * Sets tables manually instead of relying on the reverse engineering capabilities of SchemaManager.
- *
- * @param Table[] $entityTables
- * @param Table[] $manyToManyTables
- * @psalm-param list $entityTables
- * @psalm-param list $manyToManyTables
- */
- public function setTables(array $entityTables, array $manyToManyTables): void
- {
- $this->tables = $this->manyToManyTables = $this->classToTableNames = [];
-
- foreach ($entityTables as $table) {
- $className = $this->getClassNameForTable($table->getName());
-
- $this->classToTableNames[$className] = $table->getName();
- $this->tables[$table->getName()] = $table;
- }
-
- foreach ($manyToManyTables as $table) {
- $this->manyToManyTables[$table->getName()] = $table;
- }
- }
-
- public function setInflector(Inflector $inflector): void
- {
- $this->inflector = $inflector;
- }
-
- /**
- * {@inheritDoc}
- *
- * @psalm-param class-string $className
- * @psalm-param ClassMetadata $metadata
- *
- * @template T of object
- */
- public function loadMetadataForClass(string $className, PersistenceClassMetadata $metadata): void
- {
- if (! $metadata instanceof ClassMetadata) {
- throw new TypeError(sprintf(
- 'Argument #2 passed to %s() must be an instance of %s, %s given.',
- __METHOD__,
- ClassMetadata::class,
- get_debug_type($metadata),
- ));
- }
-
- $this->reverseEngineerMappingFromDatabase();
-
- if (! isset($this->classToTableNames[$className])) {
- throw new InvalidArgumentException('Unknown class ' . $className);
- }
-
- $tableName = $this->classToTableNames[$className];
-
- $metadata->name = $className;
- $metadata->table['name'] = $tableName;
-
- $this->buildIndexes($metadata);
- $this->buildFieldMappings($metadata);
- $this->buildToOneAssociationMappings($metadata);
-
- foreach ($this->manyToManyTables as $manyTable) {
- foreach ($manyTable->getForeignKeys() as $foreignKey) {
- // foreign key maps to the table of the current entity, many to many association probably exists
- if (! (strtolower($tableName) === strtolower($foreignKey->getForeignTableName()))) {
- continue;
- }
-
- $myFk = $foreignKey;
- $otherFk = null;
-
- foreach ($manyTable->getForeignKeys() as $foreignKey) {
- if ($foreignKey !== $myFk) {
- $otherFk = $foreignKey;
- break;
- }
- }
-
- if (! $otherFk) {
- // the definition of this many to many table does not contain
- // enough foreign key information to continue reverse engineering.
- continue;
- }
-
- $localColumn = current($myFk->getLocalColumns());
-
- $associationMapping = [];
- $associationMapping['fieldName'] = $this->getFieldNameForColumn($manyTable->getName(), current($otherFk->getLocalColumns()), true);
- $associationMapping['targetEntity'] = $this->getClassNameForTable($otherFk->getForeignTableName());
-
- if (current($manyTable->getColumns())->getName() === $localColumn) {
- $associationMapping['inversedBy'] = $this->getFieldNameForColumn($manyTable->getName(), current($myFk->getLocalColumns()), true);
- $associationMapping['joinTable'] = [
- 'name' => strtolower($manyTable->getName()),
- 'joinColumns' => [],
- 'inverseJoinColumns' => [],
- ];
-
- $fkCols = $myFk->getForeignColumns();
- $cols = $myFk->getLocalColumns();
-
- for ($i = 0, $colsCount = count($cols); $i < $colsCount; $i++) {
- $associationMapping['joinTable']['joinColumns'][] = [
- 'name' => $cols[$i],
- 'referencedColumnName' => $fkCols[$i],
- ];
- }
-
- $fkCols = $otherFk->getForeignColumns();
- $cols = $otherFk->getLocalColumns();
-
- for ($i = 0, $colsCount = count($cols); $i < $colsCount; $i++) {
- $associationMapping['joinTable']['inverseJoinColumns'][] = [
- 'name' => $cols[$i],
- 'referencedColumnName' => $fkCols[$i],
- ];
- }
- } else {
- $associationMapping['mappedBy'] = $this->getFieldNameForColumn($manyTable->getName(), current($myFk->getLocalColumns()), true);
- }
-
- $metadata->mapManyToMany($associationMapping);
-
- break;
- }
- }
- }
-
- /** @throws MappingException */
- private function reverseEngineerMappingFromDatabase(): void
- {
- if ($this->tables !== null) {
- return;
- }
-
- $this->tables = $this->manyToManyTables = $this->classToTableNames = [];
-
- foreach ($this->sm->listTables() as $table) {
- $tableName = $table->getName();
- $foreignKeys = $table->getForeignKeys();
-
- $allForeignKeyColumns = [];
-
- foreach ($foreignKeys as $foreignKey) {
- $allForeignKeyColumns = array_merge($allForeignKeyColumns, $foreignKey->getLocalColumns());
- }
-
- $primaryKey = $table->getPrimaryKey();
- if ($primaryKey === null) {
- throw new MappingException(
- 'Table ' . $tableName . ' has no primary key. Doctrine does not ' .
- "support reverse engineering from tables that don't have a primary key.",
- );
- }
-
- $pkColumns = $primaryKey->getColumns();
-
- sort($pkColumns);
- sort($allForeignKeyColumns);
-
- if ($pkColumns === $allForeignKeyColumns && count($foreignKeys) === 2) {
- $this->manyToManyTables[$tableName] = $table;
- } else {
- // lower-casing is necessary because of Oracle Uppercase Tablenames,
- // assumption is lower-case + underscore separated.
- $className = $this->getClassNameForTable($tableName);
-
- $this->tables[$tableName] = $table;
- $this->classToTableNames[$className] = $tableName;
- }
- }
- }
-
- /**
- * Build indexes from a class metadata.
- */
- private function buildIndexes(ClassMetadata $metadata): void
- {
- $tableName = $metadata->table['name'];
- $indexes = $this->tables[$tableName]->getIndexes();
-
- foreach ($indexes as $index) {
- if ($index->isPrimary()) {
- continue;
- }
-
- $indexName = $index->getName();
- $indexColumns = $index->getColumns();
- $constraintType = $index->isUnique()
- ? 'uniqueConstraints'
- : 'indexes';
-
- $metadata->table[$constraintType][$indexName]['columns'] = $indexColumns;
- }
- }
-
- /**
- * Build field mapping from class metadata.
- */
- private function buildFieldMappings(ClassMetadata $metadata): void
- {
- $tableName = $metadata->table['name'];
- $columns = $this->tables[$tableName]->getColumns();
- $primaryKeys = $this->getTablePrimaryKeys($this->tables[$tableName]);
- $foreignKeys = $this->tables[$tableName]->getForeignKeys();
- $allForeignKeys = [];
-
- foreach ($foreignKeys as $foreignKey) {
- $allForeignKeys = array_merge($allForeignKeys, $foreignKey->getLocalColumns());
- }
-
- $ids = [];
- $fieldMappings = [];
-
- foreach ($columns as $column) {
- if (in_array($column->getName(), $allForeignKeys, true)) {
- continue;
- }
-
- $fieldMapping = $this->buildFieldMapping($tableName, $column);
-
- if ($primaryKeys && in_array($column->getName(), $primaryKeys, true)) {
- $fieldMapping['id'] = true;
- $ids[] = $fieldMapping;
- }
-
- $fieldMappings[] = $fieldMapping;
- }
-
- // We need to check for the columns here, because we might have associations as id as well.
- if ($ids && count($primaryKeys) === 1) {
- $metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_AUTO);
- }
-
- foreach ($fieldMappings as $fieldMapping) {
- $metadata->mapField($fieldMapping);
- }
- }
-
- /**
- * Build field mapping from a schema column definition
- *
- * @return mixed[]
- * @psalm-return array{
- * fieldName: string,
- * columnName: string,
- * type: string,
- * nullable: bool,
- * options: array{
- * unsigned?: bool,
- * fixed?: bool,
- * comment: string|null,
- * default?: mixed
- * },
- * precision?: int,
- * scale?: int,
- * length?: int|null
- * }
- */
- private function buildFieldMapping(string $tableName, Column $column): array
- {
- $fieldMapping = [
- 'fieldName' => $this->getFieldNameForColumn($tableName, $column->getName(), false),
- 'columnName' => $column->getName(),
- 'type' => Type::getTypeRegistry()->lookupName($column->getType()),
- 'nullable' => ! $column->getNotnull(),
- 'options' => [
- 'comment' => $column->getComment(),
- ],
- ];
-
- // Type specific elements
- switch ($fieldMapping['type']) {
- case Types::BLOB:
- case Types::GUID:
- case Types::SIMPLE_ARRAY:
- case Types::STRING:
- case Types::TEXT:
- $fieldMapping['length'] = $column->getLength();
- $fieldMapping['options']['fixed'] = $column->getFixed();
- break;
-
- case Types::DECIMAL:
- case Types::FLOAT:
- $fieldMapping['precision'] = $column->getPrecision();
- $fieldMapping['scale'] = $column->getScale();
- break;
-
- case Types::INTEGER:
- case Types::BIGINT:
- case Types::SMALLINT:
- $fieldMapping['options']['unsigned'] = $column->getUnsigned();
- break;
- }
-
- // Default
- $default = $column->getDefault();
- if ($default !== null) {
- $fieldMapping['options']['default'] = $default;
- }
-
- return $fieldMapping;
- }
-
- /**
- * Build to one (one to one, many to one) association mapping from class metadata.
- */
- private function buildToOneAssociationMappings(ClassMetadata $metadata): void
- {
- assert($this->tables !== null);
-
- $tableName = $metadata->table['name'];
- $primaryKeys = $this->getTablePrimaryKeys($this->tables[$tableName]);
- $foreignKeys = $this->tables[$tableName]->getForeignKeys();
-
- foreach ($foreignKeys as $foreignKey) {
- $foreignTableName = $foreignKey->getForeignTableName();
- $fkColumns = $foreignKey->getLocalColumns();
- $fkForeignColumns = $foreignKey->getForeignColumns();
- $localColumn = current($fkColumns);
- $associationMapping = [
- 'fieldName' => $this->getFieldNameForColumn($tableName, $localColumn, true),
- 'targetEntity' => $this->getClassNameForTable($foreignTableName),
- ];
-
- if (isset($metadata->fieldMappings[$associationMapping['fieldName']])) {
- $associationMapping['fieldName'] .= '2'; // "foo" => "foo2"
- }
-
- if ($primaryKeys && in_array($localColumn, $primaryKeys, true)) {
- $associationMapping['id'] = true;
- }
-
- for ($i = 0, $fkColumnsCount = count($fkColumns); $i < $fkColumnsCount; $i++) {
- $associationMapping['joinColumns'][] = [
- 'name' => $fkColumns[$i],
- 'referencedColumnName' => $fkForeignColumns[$i],
- ];
- }
-
- // Here we need to check if $fkColumns are the same as $primaryKeys
- if (! array_diff($fkColumns, $primaryKeys)) {
- $metadata->mapOneToOne($associationMapping);
- } else {
- $metadata->mapManyToOne($associationMapping);
- }
- }
- }
-
- /**
- * Retrieve schema table definition primary keys.
- *
- * @return string[]
- */
- private function getTablePrimaryKeys(Table $table): array
- {
- try {
- return $table->getPrimaryKey()->getColumns();
- } catch (SchemaException) {
- // Do nothing
- }
-
- return [];
- }
-
- /**
- * Returns the mapped class name for a table if it exists. Otherwise return "classified" version.
- *
- * @psalm-return class-string
- */
- private function getClassNameForTable(string $tableName): string
- {
- if (isset($this->classNamesForTables[$tableName])) {
- return $this->namespace . $this->classNamesForTables[$tableName];
- }
-
- return $this->namespace . $this->inflector->classify(strtolower($tableName));
- }
-
- /**
- * Return the mapped field name for a column, if it exists. Otherwise return camelized version.
- *
- * @param bool $fk Whether the column is a foreignkey or not.
- */
- private function getFieldNameForColumn(
- string $tableName,
- string $columnName,
- bool $fk = false,
- ): string {
- if (isset($this->fieldNamesForColumns[$tableName], $this->fieldNamesForColumns[$tableName][$columnName])) {
- return $this->fieldNamesForColumns[$tableName][$columnName];
- }
-
- $columnName = strtolower($columnName);
-
- // Replace _id if it is a foreignkey column
- if ($fk) {
- $columnName = preg_replace('/_id$/', '', $columnName);
- }
-
- return $this->inflector->camelize($columnName);
- }
-}
diff --git a/tests/Tests/ORM/Functional/DatabaseDriverTest.php b/tests/Tests/ORM/Functional/DatabaseDriverTest.php
deleted file mode 100644
index f2ef9e58f62..00000000000
--- a/tests/Tests/ORM/Functional/DatabaseDriverTest.php
+++ /dev/null
@@ -1,214 +0,0 @@
-useModelSet('cms');
-
- parent::setUp();
-
- $this->schemaManager = $this->createSchemaManager();
- }
-
- #[Group('DDC-2059')]
- public function testIssue2059(): void
- {
- $user = new Table('ddc2059_user');
- $user->addColumn('id', 'integer');
- $user->setPrimaryKey(['id']);
- $project = new Table('ddc2059_project');
- $project->addColumn('id', 'integer');
- $project->addColumn('user_id', 'integer');
- $project->addColumn('user', 'string');
- $project->setPrimaryKey(['id']);
- $project->addForeignKeyConstraint('ddc2059_user', ['user_id'], ['id']);
-
- $metadata = $this->convertToClassMetadata([$project, $user], []);
-
- self::assertTrue(isset($metadata['Ddc2059Project']->fieldMappings['user']));
- self::assertTrue(isset($metadata['Ddc2059Project']->associationMappings['user2']));
- }
-
- public function testLoadMetadataFromDatabase(): void
- {
- $table = new Table('dbdriver_foo');
- $table->addColumn('id', 'integer');
- $table->setPrimaryKey(['id']);
- $table->addColumn('bar', 'string', ['notnull' => false, 'length' => 200]);
-
- $this->dropAndCreateTable($table);
-
- $metadatas = $this->extractClassMetadata(['DbdriverFoo']);
-
- self::assertArrayHasKey('DbdriverFoo', $metadatas);
- $metadata = $metadatas['DbdriverFoo'];
-
- self::assertArrayHasKey('id', $metadata->fieldMappings);
- self::assertEquals('id', $metadata->fieldMappings['id']->fieldName);
- self::assertEquals('id', strtolower($metadata->fieldMappings['id']->columnName));
- self::assertEquals('integer', (string) $metadata->fieldMappings['id']->type);
-
- self::assertArrayHasKey('bar', $metadata->fieldMappings);
- self::assertEquals('bar', $metadata->fieldMappings['bar']->fieldName);
- self::assertEquals('bar', strtolower($metadata->fieldMappings['bar']->columnName));
- self::assertEquals('string', (string) $metadata->fieldMappings['bar']->type);
- self::assertEquals(200, $metadata->fieldMappings['bar']->length);
- self::assertTrue($metadata->fieldMappings['bar']->nullable);
- }
-
- public function testLoadMetadataWithForeignKeyFromDatabase(): void
- {
- $tableB = new Table('dbdriver_bar');
- $tableB->addColumn('id', 'integer');
- $tableB->setPrimaryKey(['id']);
-
- $this->dropAndCreateTable($tableB);
-
- $tableA = new Table('dbdriver_baz');
- $tableA->addColumn('id', 'integer');
- $tableA->setPrimaryKey(['id']);
- $tableA->addColumn('bar_id', 'integer');
- $tableA->addForeignKeyConstraint('dbdriver_bar', ['bar_id'], ['id']);
-
- $this->dropAndCreateTable($tableA);
-
- $metadatas = $this->extractClassMetadata(['DbdriverBar', 'DbdriverBaz']);
-
- self::assertArrayHasKey('DbdriverBaz', $metadatas);
- $bazMetadata = $metadatas['DbdriverBaz'];
-
- self::assertArrayNotHasKey('barId', $bazMetadata->fieldMappings, "The foreign Key field should not be inflected as 'barId' field, its an association.");
- self::assertArrayHasKey('id', $bazMetadata->fieldMappings);
-
- $bazMetadata->associationMappings = array_change_key_case($bazMetadata->associationMappings, CASE_LOWER);
-
- self::assertArrayHasKey('bar', $bazMetadata->associationMappings);
- self::assertTrue($bazMetadata->associationMappings['bar']->isManyToOne());
- }
-
- public function testDetectManyToManyTables(): void
- {
- $metadatas = $this->extractClassMetadata(['CmsUsers', 'CmsGroups', 'CmsTags']);
-
- self::assertArrayHasKey('CmsUsers', $metadatas, 'CmsUsers entity was not detected.');
- self::assertArrayHasKey('CmsGroups', $metadatas, 'CmsGroups entity was not detected.');
- self::assertArrayHasKey('CmsTags', $metadatas, 'CmsTags entity was not detected.');
-
- self::assertEquals(3, count($metadatas['CmsUsers']->associationMappings));
- self::assertArrayHasKey('group', $metadatas['CmsUsers']->associationMappings);
- self::assertEquals(1, count($metadatas['CmsGroups']->associationMappings));
- self::assertArrayHasKey('user', $metadatas['CmsGroups']->associationMappings);
- self::assertEquals(1, count($metadatas['CmsTags']->associationMappings));
- self::assertArrayHasKey('user', $metadatas['CmsGroups']->associationMappings);
- }
-
- public function testIgnoreManyToManyTableWithoutFurtherForeignKeyDetails(): void
- {
- $tableB = new Table('dbdriver_bar');
- $tableB->addColumn('id', 'integer');
- $tableB->setPrimaryKey(['id']);
-
- $tableA = new Table('dbdriver_baz');
- $tableA->addColumn('id', 'integer');
- $tableA->setPrimaryKey(['id']);
-
- $tableMany = new Table('dbdriver_bar_baz');
- $tableMany->addColumn('bar_id', 'integer');
- $tableMany->addColumn('baz_id', 'integer');
- $tableMany->addForeignKeyConstraint('dbdriver_bar', ['bar_id'], ['id']);
-
- $metadatas = $this->convertToClassMetadata([$tableA, $tableB], [$tableMany]);
-
- self::assertEquals(0, count($metadatas['DbdriverBaz']->associationMappings), 'no association mappings should be detected.');
- }
-
- public function testLoadMetadataFromDatabaseDetail(): void
- {
- $table = new Table('dbdriver_foo');
-
- $table->addColumn('id', 'integer', ['unsigned' => true]);
- $table->setPrimaryKey(['id']);
- $table->addColumn('column_unsigned', 'integer', ['unsigned' => true]);
- $table->addColumn('column_comment', 'string', ['length' => 16, 'comment' => 'test_comment']);
- $table->addColumn('column_default', 'string', ['length' => 16, 'default' => 'test_default']);
- $table->addColumn('column_decimal', 'decimal', ['precision' => 4, 'scale' => 3]);
-
- $table->addColumn('column_index1', 'string', ['length' => 16]);
- $table->addColumn('column_index2', 'string', ['length' => 16]);
- $table->addIndex(['column_index1', 'column_index2'], 'index1');
-
- $table->addColumn('column_unique_index1', 'string', ['length' => 16]);
- $table->addColumn('column_unique_index2', 'string', ['length' => 16]);
- $table->addUniqueIndex(['column_unique_index1', 'column_unique_index2'], 'unique_index1');
-
- $this->dropAndCreateTable($table);
-
- $metadatas = $this->extractClassMetadata(['DbdriverFoo']);
-
- self::assertArrayHasKey('DbdriverFoo', $metadatas);
-
- $metadata = $metadatas['DbdriverFoo'];
-
- self::assertArrayHasKey('id', $metadata->fieldMappings);
- self::assertEquals('id', $metadata->fieldMappings['id']->fieldName);
- self::assertEquals('id', strtolower($metadata->fieldMappings['id']->columnName));
- self::assertEquals('integer', (string) $metadata->fieldMappings['id']->type);
-
- if (self::supportsUnsignedInteger($this->_em->getConnection()->getDatabasePlatform())) {
- self::assertArrayHasKey('columnUnsigned', $metadata->fieldMappings);
- self::assertTrue($metadata->fieldMappings['columnUnsigned']->options['unsigned']);
- }
-
- self::assertArrayHasKey('columnComment', $metadata->fieldMappings);
- self::assertEquals('test_comment', $metadata->fieldMappings['columnComment']->options['comment']);
-
- self::assertArrayHasKey('columnDefault', $metadata->fieldMappings);
- self::assertEquals('test_default', $metadata->fieldMappings['columnDefault']->options['default']);
-
- self::assertArrayHasKey('columnDecimal', $metadata->fieldMappings);
- self::assertEquals(4, $metadata->fieldMappings['columnDecimal']->precision);
- self::assertEquals(3, $metadata->fieldMappings['columnDecimal']->scale);
-
- self::assertNotEmpty($metadata->table['indexes']['index1']['columns']);
- self::assertEquals(
- ['column_index1', 'column_index2'],
- $metadata->table['indexes']['index1']['columns'],
- );
-
- self::assertNotEmpty($metadata->table['uniqueConstraints']['unique_index1']['columns']);
- self::assertEquals(
- ['column_unique_index1', 'column_unique_index2'],
- $metadata->table['uniqueConstraints']['unique_index1']['columns'],
- );
- }
-
- private static function supportsUnsignedInteger(AbstractPlatform $platform): bool
- {
- // FIXME: Condition here is fugly.
- // NOTE: PostgreSQL and SQL SERVER do not support UNSIGNED integer
-
- return ! $platform instanceof SQLServerPlatform
- && ! $platform instanceof PostgreSQLPlatform;
- }
-}
diff --git a/tests/Tests/ORM/Functional/DatabaseDriverTestCase.php b/tests/Tests/ORM/Functional/DatabaseDriverTestCase.php
deleted file mode 100644
index 7a9039cfe11..00000000000
--- a/tests/Tests/ORM/Functional/DatabaseDriverTestCase.php
+++ /dev/null
@@ -1,69 +0,0 @@
- */
- protected function convertToClassMetadata(array $entityTables, array $manyTables = []): array
- {
- $sm = $this->createSchemaManager();
- $driver = new DatabaseDriver($sm);
- $driver->setTables($entityTables, $manyTables);
-
- $metadatas = [];
- foreach ($driver->getAllClassNames() as $className) {
- $class = new ClassMetadata($className);
- $driver->loadMetadataForClass($className, $class);
- $metadatas[$className] = $class;
- }
-
- return $metadatas;
- }
-
- /**
- * @param string[] $classNames
- *
- * @psalm-return array
- */
- protected function extractClassMetadata(array $classNames): array
- {
- $classNames = array_map('strtolower', $classNames);
- $metadatas = [];
-
- $sm = $this->createSchemaManager();
- $driver = new DatabaseDriver($sm);
-
- foreach ($driver->getAllClassNames() as $className) {
- if (! in_array(strtolower($className), $classNames, true)) {
- continue;
- }
-
- $class = new ClassMetadata($className);
- $driver->loadMetadataForClass($className, $class);
- $metadatas[$className] = $class;
- }
-
- if (count($metadatas) !== count($classNames)) {
- self::fail("Have not found all classes matching the names '" . implode(', ', $classNames) . "' only tables " . implode(', ', array_keys($metadatas)));
- }
-
- return $metadatas;
- }
-}
diff --git a/tests/Tests/ORM/Functional/Ticket/DDC2359Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2359Test.php
index b02a8dfe62f..106fc3b9368 100644
--- a/tests/Tests/ORM/Functional/Ticket/DDC2359Test.php
+++ b/tests/Tests/ORM/Functional/Ticket/DDC2359Test.php
@@ -14,12 +14,11 @@
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Id;
-use Doctrine\Persistence\Mapping\Driver\MappingDriver;
+use Doctrine\Tests\OrmTestCase;
use PHPUnit\Framework\Attributes\Group;
-use PHPUnit\Framework\TestCase;
#[Group('DDC-2359')]
-class DDC2359Test extends TestCase
+class DDC2359Test extends OrmTestCase
{
/**
* Verifies that {@see \Doctrine\ORM\Mapping\ClassMetadataFactory::wakeupReflection} is
@@ -27,8 +26,8 @@ class DDC2359Test extends TestCase
*/
public function testIssue(): void
{
- $mockDriver = $this->createMock(MappingDriver::class);
- $mockMetadata = $this->createMock(ClassMetadata::class);
+ $mockDriver = $this->createAttributeDriver();
+ $mockMetadata = new ClassMetadata(DDC2359Foo::class);
$entityManager = $this->createMock(EntityManager::class);
$metadataFactory = $this->getMockBuilder(ClassMetadataFactory::class)
@@ -45,8 +44,8 @@ public function testIssue(): void
->method('getMetadataDriverImpl')
->will(self::returnValue($mockDriver));
- $entityManager->expects(self::any())->method('getConfiguration')->will(self::returnValue($configuration));
- $entityManager->expects(self::any())->method('getConnection')->will(self::returnValue($connection));
+ $entityManager->method('getConfiguration')->will(self::returnValue($configuration));
+ $entityManager->method('getConnection')->will(self::returnValue($connection));
$entityManager
->method('getEventManager')
->will(self::returnValue($this->createMock(EventManager::class)));
@@ -56,8 +55,6 @@ public function testIssue(): void
$metadataFactory->setEntityManager($entityManager);
- $mockMetadata->method('getName')->willReturn(DDC2359Foo::class);
-
self::assertSame($mockMetadata, $metadataFactory->getMetadataFor(DDC2359Foo::class));
}
}
@@ -65,9 +62,8 @@ public function testIssue(): void
#[Entity]
class DDC2359Foo
{
- /** @var int */
#[Id]
#[Column(type: 'integer')]
#[GeneratedValue]
- public $id;
+ public int $id;
}
diff --git a/tests/Tests/ORM/Functional/Ticket/DDC2387Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2387Test.php
deleted file mode 100644
index 997f7e5e49b..00000000000
--- a/tests/Tests/ORM/Functional/Ticket/DDC2387Test.php
+++ /dev/null
@@ -1,32 +0,0 @@
-addColumn('id', 'integer');
- $product->setPrimaryKey(['id']);
-
- $attributes = new Table('ddc2387_attributes');
- $attributes->addColumn('product_id', 'integer');
- $attributes->addColumn('attribute_name', 'string');
- $attributes->setPrimaryKey(['product_id', 'attribute_name']);
- $attributes->addForeignKeyConstraint('ddc2387_product', ['product_id'], ['product_id']);
-
- $metadata = $this->convertToClassMetadata([$product, $attributes], []);
-
- self::assertEquals(ClassMetadata::GENERATOR_TYPE_NONE, $metadata['Ddc2387Attributes']->generatorType);
- self::assertEquals(ClassMetadata::GENERATOR_TYPE_AUTO, $metadata['Ddc2387Product']->generatorType);
- }
-}
diff --git a/tests/Tests/ORM/Functional/Ticket/GH6682Test.php b/tests/Tests/ORM/Functional/Ticket/GH6682Test.php
index 440441eb854..62206c24713 100644
--- a/tests/Tests/ORM/Functional/Ticket/GH6682Test.php
+++ b/tests/Tests/ORM/Functional/Ticket/GH6682Test.php
@@ -19,7 +19,7 @@ public function testIssue(): void
'initialValue' => '',
];
- $classMetadata = new ClassMetadata('test_entity');
+ $classMetadata = new ClassMetadata(self::class);
$classMetadata->setSequenceGeneratorDefinition($parsedDefinition);
self::assertSame(
diff --git a/tests/Tests/ORM/Functional/Ticket/GH7684Test.php b/tests/Tests/ORM/Functional/Ticket/GH7684Test.php
deleted file mode 100644
index 654b1cd8655..00000000000
--- a/tests/Tests/ORM/Functional/Ticket/GH7684Test.php
+++ /dev/null
@@ -1,34 +0,0 @@
-addColumn('id', 'integer');
- $table1->setPrimaryKey(['id']);
-
- $table2 = new Table('GH7684_identity_test_assoc_table');
- $table2->addColumn('id', 'integer');
- $table2->addColumn('gh7684_identity_test_id', 'integer');
- $table2->setPrimaryKey(['id']);
- $table2->addForeignKeyConstraint('GH7684_identity_test', ['gh7684_identity_test_id'], ['id']);
-
- $metadatas = $this->convertToClassMetadata([$table1, $table2]);
- $metadata = $metadatas['Gh7684IdentityTestAssocTable'];
-
- self::assertArrayHasKey('gh7684IdentityTest', $metadata->associationMappings);
- }
-}
diff --git a/tests/Tests/ORM/Mapping/ClassMetadataTest.php b/tests/Tests/ORM/Mapping/ClassMetadataTest.php
index e5619aefb35..ac9e2342db4 100644
--- a/tests/Tests/ORM/Mapping/ClassMetadataTest.php
+++ b/tests/Tests/ORM/Mapping/ClassMetadataTest.php
@@ -19,7 +19,6 @@
use Doctrine\ORM\Mapping\OneToManyAssociationMapping;
use Doctrine\ORM\Mapping\UnderscoreNamingStrategy;
use Doctrine\Persistence\Mapping\RuntimeReflectionService;
-use Doctrine\Persistence\Mapping\StaticReflectionService;
use Doctrine\Tests\DbalTypes\CustomIdObject;
use Doctrine\Tests\DbalTypes\CustomIdObjectType;
use Doctrine\Tests\DbalTypes\CustomIntType;
@@ -972,32 +971,6 @@ public function testCanInstantiateInternalPhpClassSubclassFromUnserializedMetada
self::assertInstanceOf(MyArrayObjectEntity::class, $classMetadata->newInstance());
}
- public function testWakeupReflectionWithEmbeddableAndStaticReflectionService(): void
- {
- $classMetadata = new ClassMetadata(TestEntity1::class);
-
- $classMetadata->mapEmbedded(
- [
- 'fieldName' => 'test',
- 'class' => TestEntity1::class,
- 'columnPrefix' => false,
- ],
- );
-
- $field = [
- 'fieldName' => 'test.embeddedProperty',
- 'type' => 'string',
- 'originalClass' => TestEntity1::class,
- 'declaredField' => 'test',
- 'originalField' => 'embeddedProperty',
- ];
-
- $classMetadata->mapField($field);
- $classMetadata->wakeupReflection(new StaticReflectionService());
-
- self::assertEquals(['test' => null, 'test.embeddedProperty' => null], $classMetadata->getReflectionProperties());
- }
-
public function testGetColumnNamesWithGivenFieldNames(): void
{
$metadata = new ClassMetadata(CmsUser::class);
diff --git a/tests/Tests/ORM/Query/SqlExpressionVisitorTest.php b/tests/Tests/ORM/Query/SqlExpressionVisitorTest.php
index 3e2a3e30eda..27469accc47 100644
--- a/tests/Tests/ORM/Query/SqlExpressionVisitorTest.php
+++ b/tests/Tests/ORM/Query/SqlExpressionVisitorTest.php
@@ -20,7 +20,7 @@ class SqlExpressionVisitorTest extends TestCase
protected function setUp(): void
{
$this->persister = $this->createMock(BasicEntityPersister::class);
- $this->classMetadata = new ClassMetadata('Dummy');
+ $this->classMetadata = new ClassMetadata(self::class);
$this->visitor = new SqlExpressionVisitor($this->persister, $this->classMetadata);
}
diff --git a/tests/Tests/ORM/Utility/HierarchyDiscriminatorResolverTest.php b/tests/Tests/ORM/Utility/HierarchyDiscriminatorResolverTest.php
index 2f4d789c809..c1aa15c2c04 100644
--- a/tests/Tests/ORM/Utility/HierarchyDiscriminatorResolverTest.php
+++ b/tests/Tests/ORM/Utility/HierarchyDiscriminatorResolverTest.php
@@ -13,11 +13,11 @@ class HierarchyDiscriminatorResolverTest extends TestCase
{
public function testResolveDiscriminatorsForClass(): void
{
- $childClassMetadata = new ClassMetadata('ChildEntity');
+ $childClassMetadata = new ClassMetadata(self::class);
$childClassMetadata->name = 'Some\Class\Child\Name';
$childClassMetadata->discriminatorValue = 'child-discriminator';
- $classMetadata = new ClassMetadata('Entity');
+ $classMetadata = new ClassMetadata(self::class);
$classMetadata->subClasses = [$childClassMetadata->name];
$classMetadata->name = 'Some\Class\Name';
$classMetadata->discriminatorValue = 'discriminator';
@@ -41,7 +41,7 @@ public function testResolveDiscriminatorsForClass(): void
public function testResolveDiscriminatorsForClassWithNoSubclasses(): void
{
- $classMetadata = new ClassMetadata('Entity');
+ $classMetadata = new ClassMetadata(self::class);
$classMetadata->subClasses = [];
$classMetadata->name = 'Some\Class\Name';
$classMetadata->discriminatorValue = 'discriminator';