From 2b53eb672edb4bf513e0b4c5d322d3728977037c Mon Sep 17 00:00:00 2001 From: jygaulier Date: Mon, 13 Jan 2025 11:50:57 +0100 Subject: [PATCH] add `app:workspace:delete` cli with debug log (-vvv) (#509) --- .../src/Command/DeleteWorkspaceCommand.php | 70 +++++++++++++++++++ .../src/Doctrine/Delete/WorkspaceDelete.php | 37 +++++++--- 2 files changed, 98 insertions(+), 9 deletions(-) create mode 100644 databox/api/src/Command/DeleteWorkspaceCommand.php diff --git a/databox/api/src/Command/DeleteWorkspaceCommand.php b/databox/api/src/Command/DeleteWorkspaceCommand.php new file mode 100644 index 000000000..1e56319a0 --- /dev/null +++ b/databox/api/src/Command/DeleteWorkspaceCommand.php @@ -0,0 +1,70 @@ +setDescription('Delete a workspace') + ->addArgument('workspace-id', InputArgument::REQUIRED) + ->addOption('force', 'f', InputOption::VALUE_NONE, 'Force the deletion without asking for confirmation') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $workspaceId = $input->getArgument('workspace-id'); + $workspace = $this->em->find(Workspace::class, $workspaceId); + if (!$workspace instanceof Workspace) { + throw new \InvalidArgumentException(sprintf('Workspace "%s" not found', $workspaceId)); + } + + if(!$input->getOption('force')) { + $output->writeln(sprintf('This action will delete the workspace "%s" (%s) and all its content.', $workspace->getName(), $workspace->getId())); + $helper = $this->getHelper('question'); + $question = new ConfirmationQuestion('Continue? (y/n) ', false); + if (!$helper->ask($input, $output, $question)) { + return 0; + } + } + + $output->writeln(sprintf('Deleting workspace "%s" (%s)...', $workspace->getName(), $workspace->getId())); + + if (null === $workspace->getDeletedAt()) { + $workspace->setDeletedAt(new \DateTimeImmutable()); + $this->em->flush(); + } + + $this->workspaceDelete->deleteWorkspace($workspaceId, $this->logger); + $output->writeln('Done.'); + + return 0; + } +} diff --git a/databox/api/src/Doctrine/Delete/WorkspaceDelete.php b/databox/api/src/Doctrine/Delete/WorkspaceDelete.php index 8611ab0c9..b31c9d9de 100644 --- a/databox/api/src/Doctrine/Delete/WorkspaceDelete.php +++ b/databox/api/src/Doctrine/Delete/WorkspaceDelete.php @@ -15,16 +15,19 @@ use App\Entity\Core\RenditionDefinition; use App\Entity\Core\Tag; use App\Entity\Core\Workspace; +use App\Entity\Integration\WorkspaceIntegration; use App\Entity\Template\AssetDataTemplate; use Doctrine\ORM\EntityManagerInterface; +use Psr\Log\LoggerInterface; final readonly class WorkspaceDelete { public function __construct( private EntityManagerInterface $em, - private CollectionDelete $collectionDelete, - private IndexCleaner $indexCleaner, - private SoftDeleteToggler $softDeleteToggler, + private CollectionDelete $collectionDelete, + private IndexCleaner $indexCleaner, + private SoftDeleteToggler $softDeleteToggler, + private LoggerInterface $logger, ) { } @@ -38,6 +41,7 @@ public function deleteWorkspace(string $workspaceId): void throw new \InvalidArgumentException(sprintf('Workspace "%s" is not marked as deleted', $workspace->getId())); } + $this->logger->debug('Cleaning index.'); $this->indexCleaner->removeWorkspaceFromIndex($workspaceId); DeferredIndexListener::disable(); @@ -46,12 +50,12 @@ public function deleteWorkspace(string $workspaceId): void $this->em->beginTransaction(); $configuration = $this->em->getConnection()->getConfiguration(); - $logger = $configuration->getSQLLogger(); + $sqlLogger = $configuration->getSQLLogger(); $configuration->setSQLLogger(); try { $collections = $this->em->getRepository(Collection::class) ->createQueryBuilder('t') - ->select('t.id') + ->select('t.id, t.title') ->andWhere('t.parent IS NULL') ->andWhere('t.workspace = :ws') ->setParameter('ws', $workspaceId) @@ -59,6 +63,7 @@ public function deleteWorkspace(string $workspaceId): void ->toIterable(); foreach ($collections as $c) { + $this->logger->debug(sprintf('Deleting collection "%s" (%s).', $c['title'] ?: '', $c['id'])); $this->collectionDelete->deleteCollection((string) $c['id'], true); } @@ -68,6 +73,15 @@ public function deleteWorkspace(string $workspaceId): void $this->deleteDependencies(AttributeDefinition::class, $workspaceId); $this->deleteDependencies(AttributeClass::class, $workspaceId); $this->deleteDependencies(AssetDataTemplate::class, $workspaceId); + $this->deleteDependencies(WorkspaceIntegration::class, $workspaceId); + + $nFiles = $this->em->getRepository(File::class) + ->createQueryBuilder('t') + ->select('COUNT(t.id)') + ->andWhere('t.workspace = :ws') + ->setParameter('ws', $workspaceId) + ->getQuery() + ->getSingleScalarResult(); $files = $this->em->getRepository(File::class) ->createQueryBuilder('t') @@ -77,13 +91,15 @@ public function deleteWorkspace(string $workspaceId): void ->getQuery() ->toIterable(); - foreach ($files as $f) { - $workspace = $this->em->find(File::class, $f['id']); - $this->em->remove($workspace); + $this->logger->debug(sprintf('Deleting %d Files', $nFiles)); + foreach ($files as $file) { + $f = $this->em->find(File::class, $file['id']); + $this->em->remove($f); $this->em->flush(); } $workspace = $this->em->find(Workspace::class, $workspaceId); + $this->logger->debug('Deleting workspace.'); $this->em->remove($workspace); $this->em->flush(); $this->em->commit(); @@ -93,12 +109,15 @@ public function deleteWorkspace(string $workspaceId): void } finally { DeferredIndexListener::enable(); $this->softDeleteToggler->enable(); - $configuration->setSQLLogger($logger); + $configuration->setSQLLogger($sqlLogger); } } private function deleteDependencies(string $entityClass, string $workspaceId): void { + $p = explode('\\', $entityClass); + $this->logger->debug(sprintf('Deleting %s(s)', array_pop($p))); + $items = $this->em->getRepository($entityClass)->findBy([ 'workspace' => $workspaceId, ]);