Skip to content

Commit

Permalink
issue #142 - remove doctrine dependency in anonymizator and stats pro…
Browse files Browse the repository at this point in the history
…vider (#144)
  • Loading branch information
pounard committed Apr 22, 2024
1 parent 396bdc3 commit 1108c71
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 46 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* [feature] ⭐️ Add Doctrine DBAL 4.0 compatibility (#140).
* [feature] ⭐️ Anonymization - Add Doctrine Embeddables support (#105).
* [feature] ⭐️ As a side effect, Doctrine ORM 3.0 should now work (#140).
* [internal] Remove `doctrine/dbal` dependency from `Anonymizator` (#142).
* [internal] Introduce `DatabaseSessionRegistry` as single entry point for plugging-in database (#142).
* [internal] Use `makinacorpus/query-builder` schema manager for DDL alteration (#140).
* [internal] Raise `makinacorpus/query-builder` dependency to version 1.5.3 (#140).

Expand Down
9 changes: 7 additions & 2 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ services:
- '@db_tools.stats_provider.factory'
tags: ['console.command']

# Database registry.
db_tools.database_session.registry:
class: MakinaCorpus\DbToolsBundle\Database\DoctrineDatabaseSessionRegistry
arguments: ['@doctrine']

# Utilities
db_tools.storage:
class: MakinaCorpus\DbToolsBundle\Storage\Storage
Expand Down Expand Up @@ -82,7 +87,7 @@ services:
# Stats providers
db_tools.stats_provider.factory:
class: MakinaCorpus\DbToolsBundle\Stats\StatsProviderFactory
arguments: ['@doctrine']
arguments: ['@db_tools.database_session.registry']

# Anonymization
db_tools.anonymization.anonymizer.registry:
Expand All @@ -91,7 +96,7 @@ services:
db_tools.anonymization.anonymizator.factory:
class: MakinaCorpus\DbToolsBundle\Anonymization\AnonymizatorFactory
arguments:
- '@doctrine'
- '@db_tools.database_session.registry'
- '@db_tools.anonymization.anonymizer.registry'
- '@logger'
tags: [{ name: monolog.logger, channel: db_tools_anonymization }]
6 changes: 1 addition & 5 deletions src/Anonymization/Anonymizator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@

namespace MakinaCorpus\DbToolsBundle\Anonymization;

use Doctrine\DBAL\Connection;
use MakinaCorpus\DbToolsBundle\Anonymization\Anonymizer\AbstractAnonymizer;
use MakinaCorpus\DbToolsBundle\Anonymization\Anonymizer\AnonymizerRegistry;
use MakinaCorpus\DbToolsBundle\Anonymization\Config\AnonymizationConfig;
use MakinaCorpus\DbToolsBundle\Anonymization\Config\AnonymizerConfig;
use MakinaCorpus\DbToolsBundle\Helper\Format;
use MakinaCorpus\DbToolsBundle\Helper\Output\NullOutput;
use MakinaCorpus\DbToolsBundle\Helper\Output\OutputInterface;
use MakinaCorpus\QueryBuilder\Bridge\Doctrine\DoctrineQueryBuilder;
use MakinaCorpus\QueryBuilder\DatabaseSession;
use MakinaCorpus\QueryBuilder\Error\Server\DatabaseObjectDoesNotExistError;
use MakinaCorpus\QueryBuilder\Query\Update;
Expand All @@ -30,17 +28,15 @@ class Anonymizator implements LoggerAwareInterface
use LoggerAwareTrait;

private OutputInterface $output;
private DatabaseSession $databaseSession;

public function __construct(
Connection $connection,
private DatabaseSession $databaseSession,
private AnonymizerRegistry $anonymizerRegistry,
private AnonymizationConfig $anonymizationConfig,
private ?string $salt = null,
) {
$this->logger = new NullLogger();
$this->output = new NullOutput();
$this->databaseSession = new DoctrineQueryBuilder($connection);
}

/**
Expand Down
20 changes: 12 additions & 8 deletions src/Anonymization/AnonymizatorFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@

namespace MakinaCorpus\DbToolsBundle\Anonymization;

use Doctrine\DBAL\Connection;
use Doctrine\Persistence\ManagerRegistry;
use MakinaCorpus\DbToolsBundle\Anonymization\Anonymizer\AnonymizerRegistry;
use MakinaCorpus\DbToolsBundle\Anonymization\Config\AnonymizationConfig;
use MakinaCorpus\DbToolsBundle\Anonymization\Config\Loader\LoaderInterface;
use MakinaCorpus\DbToolsBundle\Database\DatabaseSessionRegistry;
use Psr\Log\LoggerInterface;

class AnonymizatorFactory
Expand All @@ -19,33 +18,36 @@ class AnonymizatorFactory
private array $configurationLoaders = [];

public function __construct(
private ManagerRegistry $doctrineRegistry,
private DatabaseSessionRegistry $registry,
private AnonymizerRegistry $anonymizerRegistry,
private ?LoggerInterface $logger = null,
) {}

/**
* Add configuration loader.
*/
public function addConfigurationLoader(LoaderInterface $loader): void
{
$this->configurationLoaders[] = $loader;
}

/**
* Get anonymizator instance for given connection name.
*/
public function getOrCreate(string $connectionName): Anonymizator
{
if (isset($this->anonymizators[$connectionName])) {
return $this->anonymizators[$connectionName];
}

$connection = $this->doctrineRegistry->getConnection($connectionName);
\assert($connection instanceof Connection);

$config = new AnonymizationConfig($connectionName);

foreach ($this->configurationLoaders as $loader) {
$loader->load($config);
}

$anonymizator = new Anonymizator(
$connection,
$this->registry->getDatabaseSession($connectionName),
$this->anonymizerRegistry,
$config
);
Expand All @@ -58,12 +60,14 @@ public function getOrCreate(string $connectionName): Anonymizator
}

/**
* Get all anonymizators for each known connection name.
*
* @return array<string, Anonymizator>
*/
public function all(): array
{
$ret = [];
foreach (\array_keys($this->doctrineRegistry->getConnections()) as $connectionName) {
foreach ($this->registry->getConnectionNames() as $connectionName) {
$ret[$connectionName] = $this->getOrCreate($connectionName);
}

Expand Down
25 changes: 25 additions & 0 deletions src/Database/DatabaseSessionRegistry.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace MakinaCorpus\DbToolsBundle\Database;

use MakinaCorpus\QueryBuilder\DatabaseSession;

/**
* Main entry point for plugging this component to any framework.
*/
interface DatabaseSessionRegistry
{
/**
* Get all known connection names.
*
* @return string[]
*/
public function getConnectionNames(): array;

/**
* Get database session for given connection name.
*/
public function getDatabaseSession(string $connectionName): DatabaseSession;
}
31 changes: 31 additions & 0 deletions src/Database/DoctrineDatabaseSessionRegistry.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace MakinaCorpus\DbToolsBundle\Database;

use Doctrine\Persistence\ManagerRegistry;
use MakinaCorpus\QueryBuilder\Bridge\Doctrine\DoctrineQueryBuilder;
use MakinaCorpus\QueryBuilder\DatabaseSession;

/**
* doctrine/dbal based implementation.
*/
class DoctrineDatabaseSessionRegistry implements DatabaseSessionRegistry
{
public function __construct(
private ManagerRegistry $doctrineRegistry,
) {}

#[\Override]
public function getConnectionNames(): array
{
return \array_keys($this->doctrineRegistry->getConnections());
}

#[\Override]
public function getDatabaseSession(string $connectionName): DatabaseSession
{
return new DoctrineQueryBuilder($this->doctrineRegistry->getConnection($connectionName));
}
}
12 changes: 4 additions & 8 deletions src/Stats/StatsProviderFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,22 @@

namespace MakinaCorpus\DbToolsBundle\Stats;

use Doctrine\DBAL\Connection;
use Doctrine\Persistence\ManagerRegistry;
use MakinaCorpus\DbToolsBundle\Database\DatabaseSessionRegistry;
use MakinaCorpus\DbToolsBundle\Error\NotImplementedException;
use MakinaCorpus\QueryBuilder\Bridge\Doctrine\DoctrineQueryBuilder;
use MakinaCorpus\QueryBuilder\Vendor;

class StatsProviderFactory
{
public function __construct(
private ManagerRegistry $doctrineRegistry,
private DatabaseSessionRegistry $registry,
) {}

/**
* Get stats provider for given connection.
*/
public function create(?string $connectionName = null): AbstractStatsProvider
{
/** @var Connection */
$connection = $this->doctrineRegistry->getConnection($connectionName);
$session = new DoctrineQueryBuilder($connection);
$session = $this->registry->getDatabaseSession($connectionName);
$vendorName = $session->getVendorName();

$statsProvider = match ($vendorName) {
Expand All @@ -36,6 +32,6 @@ public function create(?string $connectionName = null): AbstractStatsProvider
)),
};

return new $statsProvider(new DoctrineQueryBuilder($connection));
return new $statsProvider($session);
}
}
2 changes: 1 addition & 1 deletion src/Test/FunctionalTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ protected function createAnonymizatorWithConfig(AnonymizerConfig ...$anonymizerC
}

return new Anonymizator(
$this->getDoctrineConnection(),
$this->getDatabaseSession(),
new AnonymizerRegistry(),
$config
);
Expand Down
4 changes: 2 additions & 2 deletions tests/Functional/Anonymizer/AnonymizatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public function testMultipleAnonymizersAtOnce(): void
]),
));

$anonymizator = new Anonymizator($this->getDoctrineConnection(), new AnonymizerRegistry(), $config);
$anonymizator = new Anonymizator($this->getDatabaseSession(), new AnonymizerRegistry(), $config);
$anonymizator->addAnonymizerIdColumn('table_test');
$anonymizator->anonymize();

Expand Down Expand Up @@ -95,7 +95,7 @@ public function testSerial(): void
$actual,
);

$anonymizator = new Anonymizator($this->getDoctrineConnection(), new AnonymizerRegistry(), new AnonymizationConfig());
$anonymizator = new Anonymizator($this->getDatabaseSession(), new AnonymizerRegistry(), new AnonymizationConfig());
$anonymizator->addAnonymizerIdColumn('table_test');

if (Vendor::SQLITE === $this->getDatabaseSession()->getVendorName()) {
Expand Down
35 changes: 15 additions & 20 deletions tests/Unit/Anonymization/AnonymizatorFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,28 @@

namespace MakinaCorpus\DbToolsBundle\Tests\Unit\Anonymization;

use Doctrine\DBAL\Connection;
use Doctrine\Persistence\ManagerRegistry;
use MakinaCorpus\DbToolsBundle\Anonymization\Anonymizator;
use MakinaCorpus\DbToolsBundle\Anonymization\AnonymizatorFactory;
use MakinaCorpus\DbToolsBundle\Anonymization\Config\AnonymizerConfig;
use MakinaCorpus\DbToolsBundle\Anonymization\Anonymizer\AnonymizerRegistry;
use MakinaCorpus\DbToolsBundle\Anonymization\Anonymizer\Options;
use MakinaCorpus\DbToolsBundle\Tests\Mock\TestingAnonymizationLoader;
use MakinaCorpus\DbToolsBundle\Anonymization\Config\AnonymizerConfig;
use MakinaCorpus\DbToolsBundle\Database\DatabaseSessionRegistry;
use MakinaCorpus\DbToolsBundle\Test\UnitTestCase;
use MakinaCorpus\DbToolsBundle\Tests\Mock\TestingAnonymizationLoader;

class AnonymizatorFactoryTest extends UnitTestCase
{
public function testGetOrCreateWithEmptyConfig(): void
{
$entityManager = $this->createMock(Connection::class);

$doctrineRegistry = $this->createMock(ManagerRegistry::class);
$doctrineRegistry
$databaseSessionRegistry = $this->createMock(DatabaseSessionRegistry::class);
$databaseSessionRegistry
->expects($this->exactly(1))
->method('getConnection')
->willReturn($entityManager)
->method('getDatabaseSession')
->willReturn($this->getDatabaseSession())
;

$factory = new AnonymizatorFactory(
$doctrineRegistry,
$databaseSessionRegistry,
$this->createMock(AnonymizerRegistry::class)
);
$factory->addConfigurationLoader(new TestingAnonymizationLoader());
Expand All @@ -38,9 +35,9 @@ public function testGetOrCreateWithEmptyConfig(): void
self::assertInstanceOf(Anonymizator::class, $anonymizator);
self::assertCount(0, $anonymizator->getAnonymizationConfig()->all());

$doctrineRegistry
$databaseSessionRegistry
->expects($this->exactly(1))
->method('getConnections')
->method('getConnectionNames')
->willReturn([])
;

Expand All @@ -49,17 +46,15 @@ public function testGetOrCreateWithEmptyConfig(): void

public function testGetOrCreateWithConfig(): void
{
$entityManager = $this->createMock(Connection::class);

$doctrineRegistry = $this->createMock(ManagerRegistry::class);
$doctrineRegistry
$databaseSessionRegistry = $this->createMock(DatabaseSessionRegistry::class);
$databaseSessionRegistry
->expects($this->exactly(1))
->method('getConnection')
->willReturn($entityManager)
->method('getDatabaseSession')
->willReturn($this->getDatabaseSession())
;

$factory = new AnonymizatorFactory(
$doctrineRegistry,
$databaseSessionRegistry,
$this->createMock(AnonymizerRegistry::class),
);

Expand Down

0 comments on commit 1108c71

Please sign in to comment.