Skip to content

Commit

Permalink
no issue - allow cleanup command to remove deprecated column and tabl…
Browse files Browse the repository at this point in the history
…e names from previous versions
  • Loading branch information
pounard committed Nov 21, 2024
1 parent 4a7c94c commit 2bea7f3
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 15 deletions.
73 changes: 59 additions & 14 deletions src/Anonymization/Anonymizator.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@
use MakinaCorpus\DbToolsBundle\Helper\Output\NullOutput;
use MakinaCorpus\DbToolsBundle\Helper\Output\OutputInterface;
use MakinaCorpus\QueryBuilder\DatabaseSession;
use MakinaCorpus\QueryBuilder\Vendor;
use MakinaCorpus\QueryBuilder\Error\Server\DatabaseObjectDoesNotExistError;
use MakinaCorpus\QueryBuilder\Query\Update;
use MakinaCorpus\QueryBuilder\Schema\Read\Column;
use MakinaCorpus\QueryBuilder\Schema\Read\Index;
use MakinaCorpus\QueryBuilder\Schema\Read\Table;
use MakinaCorpus\QueryBuilder\Type\Type;
use MakinaCorpus\QueryBuilder\Vendor;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\NullLogger;
Expand All @@ -27,6 +26,21 @@ class Anonymizator implements LoggerAwareInterface
{
use LoggerAwareTrait;

/**
* Used for the garbage collection/cleanup procedure, removes tables with older names.
*/
protected const DEPRECATED_JOIN_ID = [
'_anonymize_id', // @todo Remove in 3.0
'_anonymizer_id', // @todo Remove in 3.0
];

/**
* Used for the garbage collection/cleanup procedure, removes tables with older names.
*/
protected const DEPRECATED_TEMP_TABLE_PREFIX = [
'anonymizer_sample_', // @todo Remove in 3.0
];

private OutputInterface $output;

public function __construct(
Expand Down Expand Up @@ -268,6 +282,10 @@ public function clean(): void
}

/**
* @param bool $withDeprecated
* Also collect garbage from previous versions. This is not default
* because it might conflict with legit project tables. We leave this
* responsability to the user.
*
* @return array<array<string, string>>
* Each item is an array structured as such:
Expand All @@ -277,23 +295,39 @@ public function clean(): void
* 'table' => 'table_name' (only for columns and indexes)
* ]
*/
public function collectGarbage(): array
public function collectGarbage(bool $withDeprecated = false): array
{
$schemaManager = $this->databaseSession->getSchemaManager();
$garbage = [];

$prefixes = [AbstractAnonymizer::TEMP_TABLE_PREFIX];
// For backward compatibilty, removes legacy table names as well.
if ($withDeprecated) {
foreach (self::DEPRECATED_TEMP_TABLE_PREFIX as $prefix) {
$prefixes[] = $prefix;
}
}

foreach ($schemaManager->listTables() as $tableName) {
if (\str_starts_with($tableName, AbstractAnonymizer::TEMP_TABLE_PREFIX)) {
$garbage[] = ['type' => 'table', 'name' => $tableName];
} else {
$garbage = \array_merge($garbage, $this->collectGarbageInto($tableName));
$found = false;
foreach ($prefixes as $prefix) {
if (\str_starts_with($tableName, $prefix)) {
$garbage[] = ['type' => 'table', 'name' => $tableName];
$found = true;
break;
}
}

// If table is not marked for deletion, lookup for added columns.
if (!$found) {
$garbage = \array_merge($garbage, $this->collectGarbageInto($tableName, $withDeprecated));
}
}

return $garbage;
}

protected function collectGarbageInto(string $table): array
protected function collectGarbageInto(string $table, bool $withDeprecated = false): array
{
$schemaManager = $this->databaseSession->getSchemaManager();
$garbage = [];
Expand All @@ -320,15 +354,26 @@ protected function collectGarbageInto(string $table): array
}
}

$names = [AbstractAnonymizer::JOIN_ID];
// For backward compatibilty, removes legacy column names as well.
if ($withDeprecated) {
foreach (self::DEPRECATED_JOIN_ID as $name) {
$names[] = $name;
}
}

foreach ($table->getColumns() as $column) {
\assert($column instanceof Column);

if (AbstractAnonymizer::JOIN_ID === $column->getName()) {
$garbage[] = [
'type' => 'column',
'name' => $column->getName(),
'table' => $table->getName(),
];
foreach ($names as $name) {
if ($name === $column->getName()) {
$garbage[] = [
'type' => 'column',
'name' => $column->getName(),
'table' => $table->getName(),
];
break;
}
}
}

Expand Down
8 changes: 7 additions & 1 deletion src/Command/Anonymization/CleanCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ protected function configure(): void
InputOption::VALUE_OPTIONAL,
'A doctrine connection name. If not given, use default connection'
)
->addOption(
'deprecated',
'd',
InputOption::VALUE_NONE,
'Also attempt to cleanup tables and columns whose name have changed from the previous versions'
)
->addOption(
'force',
null,
Expand Down Expand Up @@ -70,7 +76,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
->setOutput(new ConsoleOutput($io))
;

$garbage = $anonymizator->collectGarbage();
$garbage = $anonymizator->collectGarbage((bool) $input->getOption('deprecated'));

if (!$garbage) {
$io->success("There is no left-overs to clean, exiting.");
Expand Down

0 comments on commit 2bea7f3

Please sign in to comment.