Skip to content

Commit

Permalink
fix DoctrineBundle 2.4 + ORM 2.9 compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
dmaicher committed Jun 1, 2021
1 parent e2ab47c commit ad3d8cc
Show file tree
Hide file tree
Showing 8 changed files with 299 additions and 64 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [x.x.x]
## [6.6.0]
### Changed
- dropped support for unmaintained Symfony versions 3.4 and 5.1
- fixed compatibility with DoctrineBundle 2.4+ and ORM 2.9+ by introducing PSR-6 compatible cache
- added dependency on `symfony/cache`

## [6.5.0]
### Changed
Expand Down
86 changes: 49 additions & 37 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,40 +1,52 @@
{
"name": "dama/doctrine-test-bundle",
"description": "Symfony bundle to isolate doctrine database tests and improve test performance",
"keywords": ["symfony", "doctrine", "tests", "isolation", "performance"],
"type": "symfony-bundle",
"license": "MIT",
"authors": [
{
"name": "David Maicher",
"email": "mail@dmaicher.de"
"name": "dama/doctrine-test-bundle",
"description": "Symfony bundle to isolate doctrine database tests and improve test performance",
"keywords": [
"symfony",
"doctrine",
"tests",
"isolation",
"performance"
],
"type": "symfony-bundle",
"license": "MIT",
"authors": [
{
"name": "David Maicher",
"email": "mail@dmaicher.de"
}
],
"require": {
"php": "^7.1 || ^8.0",
"doctrine/dbal": "^2.9.3 || ^3.0",
"doctrine/doctrine-bundle": "^1.11 || ^2.0",
"symfony/cache": "^4.4 || ^5.2",
"symfony/framework-bundle": "^4.4 || ^5.2"
},
"require-dev": {
"behat/behat": "^3.0",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
"symfony/yaml": "^4.4 || ^5.2",
"symfony/phpunit-bridge": "^5.2",
"symfony/process": "^4.4 || ^5.2",
"phpstan/phpstan": "^0.12.85"
},
"autoload": {
"psr-4": {
"DAMA\\DoctrineTestBundle\\": "src/DAMA/DoctrineTestBundle"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"extra": {
"branch-alias": {
"dev-master": "7.0.x-dev"
}
},
"config": {
"sort-packages": true
}
],
"require": {
"php": "^7.1 || ^8.0",
"symfony/framework-bundle": "^4.4 || ^5.2",
"doctrine/dbal": "^2.9.3 || ^3.0",
"doctrine/doctrine-bundle": "^1.11 || ^2.0"
},
"require-dev": {
"behat/behat": "^3.0",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
"symfony/yaml": "^4.4 || ^5.2",
"symfony/phpunit-bridge": "^5.2",
"symfony/process": "^4.4 || ^5.2",
"phpstan/phpstan": "^0.12.85"
},
"autoload": {
"psr-4": {
"DAMA\\DoctrineTestBundle\\": "src/DAMA/DoctrineTestBundle"
}
},
"autoload-dev": {
"psr-4": { "Tests\\": "tests/" }
},
"extra": {
"branch-alias": {
"dev-master": "7.0.x-dev"
}
}
}
4 changes: 3 additions & 1 deletion src/DAMA/DoctrineTestBundle/DAMADoctrineTestBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace DAMA\DoctrineTestBundle;

use DAMA\DoctrineTestBundle\DependencyInjection\DoctrineTestCompilerPass;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

Expand All @@ -14,6 +15,7 @@ class DAMADoctrineTestBundle extends Bundle
public function build(ContainerBuilder $container): void
{
parent::build($container);
$container->addCompilerPass(new DoctrineTestCompilerPass());
// lower priority than CacheCompatibilityPass from DoctrineBundle
$container->addCompilerPass(new DoctrineTestCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ public function load(array $configs, ContainerBuilder $container): void
$this->processedConfig = $this->processConfiguration($configuration, $configs);
}

/**
* @internal
*/
public function getProcessedConfig(): array
{
return $this->processedConfig;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

namespace DAMA\DoctrineTestBundle\DependencyInjection;

use DAMA\DoctrineTestBundle\Doctrine\Cache\Psr6StaticArrayCache;
use DAMA\DoctrineTestBundle\Doctrine\Cache\StaticArrayCache;
use DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticConnectionFactory;
use Doctrine\Common\Cache\Cache;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
Expand Down Expand Up @@ -53,12 +56,13 @@ public function process(ContainerBuilder $container): void

foreach ($cacheNames as $cacheName) {
$cacheServiceId = sprintf($cacheName, $name);
if ($container->hasAlias($cacheServiceId)) {
$container->removeAlias($cacheServiceId);

if (!$container->has($cacheServiceId)) {
// might happen if ORM is not used
continue;
}
$cache = new Definition(StaticArrayCache::class);
$cache->addMethodCall('setNamespace', [sha1($cacheServiceId)]); //make sure we have no key collisions
$container->setDefinition($cacheServiceId, $cache);

$this->registerStaticCache($container, $container->findDefinition($cacheServiceId), $cacheServiceId);
}
}
}
Expand All @@ -80,4 +84,28 @@ private function addConnectionOptions(ContainerBuilder $container, string $name)
$connectionOptions['dama.connection_name'] = $name;
$connectionDefinition->replaceArgument(0, $connectionOptions);
}

private function registerStaticCache(
ContainerBuilder $container,
Definition $originalCacheServiceDefinition,
string $cacheServiceId
): void {
$cache = new Definition();
$namespace = sha1($cacheServiceId);

if (is_a($originalCacheServiceDefinition->getClass(), CacheItemPoolInterface::class, true)) {
$cache->setClass(Psr6StaticArrayCache::class);
$cache->setArgument(0, $namespace); //make sure we have no key collisions
} elseif (is_a($originalCacheServiceDefinition->getClass(), Cache::class, true)) {
$cache->setClass(StaticArrayCache::class);
$cache->addMethodCall('setNamespace', [$namespace]); //make sure we have no key collisions
} else {
throw new \InvalidArgumentException(sprintf('Unsupported cache class "%s" found on service "%s".', $originalCacheServiceDefinition->getClass(), $cacheServiceId));
}

if ($container->hasAlias($cacheServiceId)) {
$container->removeAlias($cacheServiceId);
}
$container->setDefinition($cacheServiceId, $cache);
}
}
108 changes: 108 additions & 0 deletions src/DAMA/DoctrineTestBundle/Doctrine/Cache/Psr6StaticArrayCache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php

namespace DAMA\DoctrineTestBundle\Doctrine\Cache;

use Psr\Cache\CacheItemInterface;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\ArrayAdapter;

final class Psr6StaticArrayCache implements CacheItemPoolInterface
{
/**
* @var array<string, ArrayAdapter>
*/
private static $adaptersByNamespace;

/**
* @var ArrayAdapter
*/
private $adapter;

public function __construct(string $namespace)
{
if (!isset(self::$adaptersByNamespace[$namespace])) {
self::$adaptersByNamespace[$namespace] = new ArrayAdapter(0, false);
}
$this->adapter = self::$adaptersByNamespace[$namespace];
}

/**
* @internal
*/
public static function reset(): void
{
self::$adaptersByNamespace = [];
}

/**
* {@inheritdoc}
*/
public function getItem($key)
{
return $this->adapter->getItem($key);
}

/**
* {@inheritdoc}
*/
public function getItems(array $keys = [])
{
return $this->adapter->getItems($keys);
}

/**
* {@inheritdoc}
*/
public function hasItem($key)
{
return $this->adapter->hasItem($key);
}

/**
* {@inheritdoc}
*/
public function clear()
{
return $this->adapter->clear();
}

/**
* {@inheritdoc}
*/
public function deleteItem($key)
{
return $this->adapter->deleteItem($key);
}

/**
* {@inheritdoc}
*/
public function deleteItems(array $keys)
{
return $this->adapter->deleteItems($keys);
}

/**
* {@inheritdoc}
*/
public function save(CacheItemInterface $item)
{
return $this->adapter->save($item);
}

/**
* {@inheritdoc}
*/
public function saveDeferred(CacheItemInterface $item)
{
return $this->adapter->saveDeferred($item);
}

/**
* {@inheritdoc}
*/
public function commit()
{
return $this->adapter->commit();
}
}
Loading

0 comments on commit ad3d8cc

Please sign in to comment.