Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

!!! FEATURE: update to doctrine/dbal version 3 #2637

Merged
merged 37 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
62fdca8
Update doctrine/dbal requirement from ^2.13 to ^3.2
dependabot[bot] Nov 29, 2021
a3d3b7e
TASK: Update doctrine dependencies
albe Apr 4, 2022
e07cefc
TASK: Adapt JsonArrayType to deprecated Doctrine JsonArrayType
albe Apr 4, 2022
f0ab947
TASK: Remove usage of deprecated `ping()` method
albe Apr 4, 2022
c726c64
TASK: Adjust PersistenceManagerTest to new ping method
albe Apr 4, 2022
b17b9f0
TASK: Extract ping dummy query into own method
albe Apr 4, 2022
aa59dff
TASK: Adjust tests to extracted `ping()` method
albe Apr 4, 2022
9797657
TASK: Mock `PersistenceManager::ping()` method
albe Apr 4, 2022
ec0969f
Apply fixes from StyleCI
StyleCIBot Apr 4, 2022
cdf2d83
TASK: Update Neos.Flow composer dependencies
mhsdesign Jan 15, 2024
449a46d
Merge remote-tracking branch 'origin/9.0' into dependabot/composer/do…
kitsunet Jun 23, 2024
c04ea8b
Adaptions for DBAL update
kitsunet Jun 26, 2024
b7a4f53
Test adjustments to dbal update
kitsunet Jun 26, 2024
d46baf3
Adjust PersistenceManagerTest to actual object structure
kitsunet Jun 26, 2024
7939c07
Cleaner cache pool instantiation
kitsunet Jun 26, 2024
1ee27f1
Integrate security hashes and flushing into new doctrine caches
kitsunet Jun 27, 2024
d29684b
Raise doctrine/orm version to get working lowest deps set
kitsunet Jun 27, 2024
ff72a62
Remove unnecessary use statement
kitsunet Jun 27, 2024
3d674e7
Apply suggestions from code review
kitsunet Jun 27, 2024
ede9a8b
Small cleanup in Exception (naming) for DBAL changes
kitsunet Jul 2, 2024
d91605e
Clarify method name for custom doctrine CachePool
kitsunet Jul 2, 2024
0e927f4
TASK: Replace deprecated `getSchemaManager` with `createSchemaManager`
mhsdesign Jul 4, 2024
3f0123d
Merge branch '9.0' into dependabot/composer/doctrine/dbal-tw-3.2
kitsunet Jul 6, 2024
8b1f7a3
Remove deprecated calls in Neos.Flow migrations
kitsunet Jul 7, 2024
f0d4fc9
Fix duplicate use statement due to upmerge
kitsunet Jul 7, 2024
e1a83f4
More deprecation cleanup for DBAL
kitsunet Jul 8, 2024
9c87f29
Bring doctrine dependencies in line
kitsunet Jul 9, 2024
3806d61
Remove DBAL object Type tests as it is deprecated
kitsunet Jul 9, 2024
3654601
Remove unused objectarray type which has no tests
kitsunet Jul 9, 2024
eb4c4aa
Merge branch '9.0' into dependabot/composer/doctrine/dbal-tw-3.2
kitsunet Jul 9, 2024
90c5b4b
Remove unnecessary use statement
kitsunet Jul 9, 2024
e69af07
Repository::findAllIterator returns iterable
kitsunet Jul 9, 2024
9fad259
Change migration folder resolving and allow override
kitsunet Jul 9, 2024
b869755
Replace deprecated doctrine SQLLogger interface
kitsunet Jul 9, 2024
d93b6b0
Undo DBALException case changes
kitsunet Jul 9, 2024
68aae78
Add missiong migration adaptions
kitsunet Jul 11, 2024
11e2348
Correct SqlLogger spelling
kitsunet Jul 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Neos.Flow/Classes/Cache/CacheManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ public function getSimpleCache(string $identifier): CacheInterface
*
* @param string $identifier
* @return CacheItemPoolInterface
* @throws NoSuchCacheException
*/
public function getCacheItemPool(string $identifier): CacheItemPoolInterface
{
Expand Down
2 changes: 1 addition & 1 deletion Neos.Flow/Classes/Command/DatabaseCommandController.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ protected function convertToCharacterSetAndCollation(string $characterSet, strin

$statements[] = 'ALTER DATABASE ' . $this->connection->quoteIdentifier($this->persistenceSettings['backendOptions']['dbname']) . ' CHARACTER SET ' . $characterSet . ' COLLATE ' . $collation;

$tableNames = $this->connection->getSchemaManager()?->listTableNames() ?? [];
$tableNames = $this->connection->createSchemaManager()->listTableNames() ?? [];
foreach ($tableNames as $tableName) {
$statements[] = 'ALTER TABLE ' . $this->connection->quoteIdentifier($tableName) . ' DEFAULT CHARACTER SET ' . $characterSet . ' COLLATE ' . $collation;
$statements[] = 'ALTER TABLE ' . $this->connection->quoteIdentifier($tableName) . ' CONVERT TO CHARACTER SET ' . $characterSet . ' COLLATE ' . $collation;
Expand Down
56 changes: 39 additions & 17 deletions Neos.Flow/Classes/Command/DoctrineCommandController.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Doctrine\Common\Util\Debug;
use Doctrine\DBAL\Exception as DBALException;
use Doctrine\Migrations\Exception\MigrationException;
use Doctrine\ORM\ORMException;
use Doctrine\ORM\Tools\ToolsException;
use Doctrine\Persistence\Mapping\ClassMetadata;
use Neos\Flow\Annotations as Flow;
Expand Down Expand Up @@ -200,7 +201,7 @@ public function updateCommand(bool $unsafeMode = false, string $output = null):
* @param boolean $dumpMappingData If set, the mapping data will be output
* @param string|null $entityClassName If given, the mapping data for just this class will be output
* @return void
* @throws \Doctrine\ORM\ORMException
* @throws ORMException
* @see neos.flow:doctrine:validate
*/
public function entityStatusCommand(bool $dumpMappingData = false, string $entityClassName = null): void
Expand Down Expand Up @@ -282,22 +283,24 @@ public function dqlCommand(int $depth = 3, string $hydrationMode = 'array', int
* available, executed and pending migrations.
*
* @param boolean $showMigrations Output a list of all migrations and their status
* @param string|null $migrationFolder Provide alternative platform folder name (as in "Mysql"), otherwise configured connection is used.
* @return void
* @throws StopCommandException
* @throws DBALException
* @throws StopCommandException
* @see neos.flow:doctrine:migrate
* @see neos.flow:doctrine:migrationexecute
* @see neos.flow:doctrine:migrationgenerate
* @see neos.flow:doctrine:migrationversion
*/
public function migrationStatusCommand(bool $showMigrations = false): void
public function migrationStatusCommand(bool $showMigrations = false, ?string $migrationFolder = null): void
{
if (!$this->isDatabaseConfigured()) {
$this->outputLine('Doctrine migration status not available, the driver and host backend options are not set in /Configuration/Settings.yaml.');
$this->quit(1);
}

$this->outputLine($this->doctrineService->getFormattedMigrationStatus($showMigrations));
$this->maybeOutputMigrationFolderWarning($migrationFolder);
$this->outputLine($this->doctrineService->getFormattedMigrationStatus($showMigrations, $migrationFolder));
}

/**
Expand All @@ -310,14 +313,15 @@ public function migrationStatusCommand(bool $showMigrations = false): void
* @param string|null $output A file to write SQL to, instead of executing it
* @param boolean $dryRun Whether to do a dry run or not
* @param boolean $quiet If set, only the executed migration versions will be output, one per line
* @param string|null $migrationFolder Provide alternative platform folder name (as in "Mysql"), otherwise configured connection is used.
* @return void
* @throws StopCommandException
* @see neos.flow:doctrine:migrationstatus
* @see neos.flow:doctrine:migrationexecute
* @see neos.flow:doctrine:migrationgenerate
* @see neos.flow:doctrine:migrationversion
*/
public function migrateCommand(string $version = 'latest', string $output = null, bool $dryRun = false, bool $quiet = false): void
public function migrateCommand(string $version = 'latest', string $output = null, bool $dryRun = false, bool $quiet = false, ?string $migrationFolder = null): void
{
if (!$this->isDatabaseConfigured()) {
$this->outputLine('Doctrine migration not possible, the driver and host backend options are not set in /Configuration/Settings.yaml.');
Expand All @@ -328,8 +332,9 @@ public function migrateCommand(string $version = 'latest', string $output = null
$this->outputLine(sprintf('The path "%s" is not writeable!', dirname($output)));
}

$this->maybeOutputMigrationFolderWarning($migrationFolder);
try {
$result = $this->doctrineService->executeMigrations($this->normalizeVersion($version), $output, $dryRun, $quiet);
$result = $this->doctrineService->executeMigrations($this->normalizeVersion($version), $output, $dryRun, $quiet, $migrationFolder);
if ($result !== '' && $quiet === false) {
$this->outputLine($result);
}
Expand Down Expand Up @@ -357,14 +362,15 @@ protected function emitAfterDatabaseMigration(): void
* @param string $direction Whether to execute the migration up (default) or down
* @param string|null $output A file to write SQL to, instead of executing it
* @param boolean $dryRun Whether to do a dry run or not
* @param string|null $migrationFolder Provide alternative platform folder name (as in "Mysql"), otherwise configured connection is used.
* @return void
* @throws StopCommandException
* @see neos.flow:doctrine:migrate
* @see neos.flow:doctrine:migrationstatus
* @see neos.flow:doctrine:migrationgenerate
* @see neos.flow:doctrine:migrationversion
*/
public function migrationExecuteCommand(string $version, string $direction = 'up', string $output = null, bool $dryRun = false): void
public function migrationExecuteCommand(string $version, string $direction = 'up', string $output = null, bool $dryRun = false, ?string $migrationFolder = null): void
{
if (!$this->isDatabaseConfigured()) {
$this->outputLine('Doctrine migration not possible, the driver and host backend options are not set in /Configuration/Settings.yaml.');
Expand All @@ -375,8 +381,9 @@ public function migrationExecuteCommand(string $version, string $direction = 'up
$this->outputLine(sprintf('The path "%s" is not writeable!', dirname($output)));
}

$this->maybeOutputMigrationFolderWarning($migrationFolder);
try {
$this->outputLine($this->doctrineService->executeMigration($this->normalizeVersion($version), $direction, $output, $dryRun));
$this->outputLine($this->doctrineService->executeMigration($this->normalizeVersion($version), $direction, $output, $dryRun, $migrationFolder));
} catch (\Exception $exception) {
$this->handleException($exception);
}
Expand All @@ -391,15 +398,17 @@ public function migrationExecuteCommand(string $version, string $direction = 'up
* @param string $version The migration to execute
* @param boolean $add The migration to mark as migrated
* @param boolean $delete The migration to mark as not migrated
* @param string|null $migrationFolder Provide alternative platform folder name (as in "Mysql"), otherwise configured connection is used.
* @return void
* @throws StopCommandException
* @throws DBALException
* @throws FilesException
* @throws StopCommandException
* @see neos.flow:doctrine:migrate
* @see neos.flow:doctrine:migrationstatus
* @see neos.flow:doctrine:migrationexecute
* @see neos.flow:doctrine:migrationgenerate
*/
public function migrationVersionCommand(string $version, bool $add = false, bool $delete = false): void
public function migrationVersionCommand(string $version, bool $add = false, bool $delete = false, ?string $migrationFolder = null): void
{
if (!$this->isDatabaseConfigured()) {
$this->outputLine('Doctrine migration not possible, the driver and host backend options are not set in /Configuration/Settings.yaml.');
Expand All @@ -410,8 +419,9 @@ public function migrationVersionCommand(string $version, bool $add = false, bool
throw new \InvalidArgumentException('You must specify whether you want to --add or --delete the specified version.');
}

$this->maybeOutputMigrationFolderWarning($migrationFolder);
try {
$this->doctrineService->markAsMigrated($this->normalizeVersion($version), $add ?: false);
$this->doctrineService->markAsMigrated($this->normalizeVersion($version), $add ?: false, $migrationFolder);
} catch (MigrationException $exception) {
$this->outputLine($exception->getMessage());
$this->quit(1);
Expand Down Expand Up @@ -440,6 +450,7 @@ public function migrationVersionCommand(string $version, bool $add = false, bool
* @param boolean $diffAgainstCurrent Whether to base the migration on the current schema structure
* @param string|null $filterExpression Only include tables/sequences matching the filter expression regexp
* @param boolean $force Generate migrations even if there are migrations left to execute
* @param string|null $migrationFolder Provide alternative platform folder name (as in "Mysql"), otherwise configured connection is used.
* @return void
* @throws DBALException
* @throws StopCommandException
Expand All @@ -449,14 +460,14 @@ public function migrationVersionCommand(string $version, bool $add = false, bool
* @see neos.flow:doctrine:migrationexecute
* @see neos.flow:doctrine:migrationversion
*/
public function migrationGenerateCommand(bool $diffAgainstCurrent = true, string $filterExpression = null, bool $force = false): void
public function migrationGenerateCommand(bool $diffAgainstCurrent = true, string $filterExpression = null, bool $force = false, ?string $migrationFolder = null): void
{
if (!$this->isDatabaseConfigured()) {
$this->outputLine('Doctrine migration generation has been SKIPPED, the driver and host backend options are not set in /Configuration/Settings.yaml.');
$this->quit(1);
}

$migrationStatus = $this->doctrineService->getMigrationStatus();
$migrationStatus = $this->doctrineService->getMigrationStatus($migrationFolder);
if ($force === false && $migrationStatus['new'] !== 0) {
$this->outputLine('There are %d new migrations available. To avoid duplication those should be executed via `doctrine:migrate` before creating additional migrations.', [$migrationStatus['new']]);
$this->quit(1);
Expand All @@ -474,7 +485,9 @@ public function migrationGenerateCommand(bool $diffAgainstCurrent = true, string
}
}

[$status, $migrationClassPathAndFilename] = $this->doctrineService->generateMigration($diffAgainstCurrent, $filterExpression);
$this->maybeOutputMigrationFolderWarning($migrationFolder);

[$status, $migrationClassPathAndFilename] = $this->doctrineService->generateMigration($diffAgainstCurrent, $filterExpression, $migrationFolder);

$this->outputLine('<info>%s</info>', [$status]);
$this->outputLine();
Expand All @@ -495,18 +508,20 @@ public function migrationGenerateCommand(bool $diffAgainstCurrent = true, string
$selectedPackage = $this->output->select('Do you want to move the migration to one of these packages?', $choices, $choices[0]);
$this->outputLine();

$migrationPlatformFolderPart = $migrationFolder ?? $this->doctrineService->getMigrationFolderName();

if ($selectedPackage !== $choices[0]) {
/** @var Package $selectedPackage */
$selectedPackage = $packages[$selectedPackage];
$targetPathAndFilename = Files::concatenatePaths([$selectedPackage->getPackagePath(), 'Migrations', $this->doctrineService->getDatabasePlatformName(), basename($migrationClassPathAndFilename)]);
/** @var Package $selectedPackage */
$targetPathAndFilename = Files::concatenatePaths([$selectedPackage->getPackagePath(), 'Migrations', $migrationPlatformFolderPart, basename($migrationClassPathAndFilename)]);
Files::createDirectoryRecursively(dirname($targetPathAndFilename));
rename($migrationClassPathAndFilename, $targetPathAndFilename);
$this->outputLine('The migration was moved to: <comment>%s</comment>', [substr($targetPathAndFilename, strlen(FLOW_PATH_ROOT))]);
$this->outputLine();
$this->outputLine('Next Steps:');
} else {
$this->outputLine('Next Steps:');
$this->outputLine(sprintf('- Move <comment>%s</comment> to YourPackage/<comment>Migrations/%s/</comment>', $migrationClassPathAndFilename, $this->doctrineService->getDatabasePlatformName()));
$this->outputLine(sprintf('- Move <comment>%s</comment> to YourPackage/<comment>Migrations/%s/</comment>', $migrationClassPathAndFilename, $migrationPlatformFolderPart));
}
$this->outputLine('- Review and adjust the generated migration.');
$this->outputLine('- (optional) execute the migration using <comment>%s doctrine:migrate</comment>', [$this->getFlowInvocationString()]);
Expand Down Expand Up @@ -553,4 +568,11 @@ private function normalizeVersion(string $version): string
}
return sprintf('Neos\Flow\Persistence\Doctrine\Migrations\Version%s', $version);
}

private function maybeOutputMigrationFolderWarning(?string $migrationFolder = null)
{
if ($migrationFolder !== null) {
$this->outputLine('<comment>Migration folder override is in effect, migration files are not searched in folder matching the configured connection but in ...Migrations/%s/</comment>', [$migrationFolder]);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ class AllowedObjectsListener
* @param OnFlushEventArgs $args
* @throws PersistenceException
*/
public function onFlush(OnFlushEventArgs $args)
public function onFlush(OnFlushEventArgs $args): void
{
$unitOfWork = $args->getEntityManager()->getUnitOfWork();
$unitOfWork = $args->getObjectManager()->getUnitOfWork();
if ($unitOfWork->getScheduledEntityInsertions() === []
&& $unitOfWork->getScheduledEntityUpdates() === []
&& $unitOfWork->getScheduledEntityDeletions() === []
Expand All @@ -87,7 +87,7 @@ public function onFlush(OnFlushEventArgs $args)
}
}

$connection = $args->getEntityManager()->getConnection();
$connection = $args->getObjectManager()->getConnection();
try {
if ($this->ping($connection) === false) {
$this->logger->info('Reconnecting the Doctrine EntityManager to the persistence backend.', LogEnvironment::fromMethodName(__METHOD__));
Expand Down Expand Up @@ -120,7 +120,7 @@ protected function ping(Connection $connection): bool
* @return void
* @throws \Neos\Flow\Persistence\Exception
*/
protected function throwExceptionIfObjectIsNotAllowed($object)
protected function throwExceptionIfObjectIsNotAllowed($object): void
{
if (!$this->allowedObjects->contains($object)) {
$message = 'Detected modified or new objects (' . get_class($object) . ', uuid:' . $this->persistenceManager->getIdentifierByObject($object) . ') to be persisted which is not allowed for "safe requests"' . chr(10) .
Expand Down
124 changes: 0 additions & 124 deletions Neos.Flow/Classes/Persistence/Doctrine/CacheAdapter.php

This file was deleted.

Loading
Loading