mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 06:52:09 +01:00
Merge pull request #8651 from alcaeus/deprecate-doctrine-metadata-cache
Introduce PSR-6 for metadata caching
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
"ext-pdo": "*",
|
||||
"composer/package-versions-deprecated": "^1.8",
|
||||
"doctrine/annotations": "^1.12",
|
||||
"doctrine/cache": "^1.9.1",
|
||||
"doctrine/cache": "^1.11.0",
|
||||
"doctrine/collections": "^1.5",
|
||||
"doctrine/common": "^3.0.3",
|
||||
"doctrine/dbal": "^2.13.0",
|
||||
@@ -30,6 +30,7 @@
|
||||
"doctrine/instantiator": "^1.3",
|
||||
"doctrine/lexer": "^1.0",
|
||||
"doctrine/persistence": "^2.0",
|
||||
"psr/cache": "^1 || ^2 || ^3",
|
||||
"symfony/console": "^3.0|^4.0|^5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
@@ -37,6 +38,7 @@
|
||||
"phpstan/phpstan": "^0.12.83",
|
||||
"phpunit/phpunit": "^7.5|^8.5|^9.4",
|
||||
"squizlabs/php_codesniffer": "3.6.0",
|
||||
"symfony/cache": "^4.4|^5.2",
|
||||
"symfony/yaml": "^3.4|^4.0|^5.0",
|
||||
"vimeo/psalm": "4.7.0"
|
||||
},
|
||||
|
||||
@@ -27,6 +27,7 @@ use Doctrine\Common\Annotations\SimpleAnnotationReader;
|
||||
use Doctrine\Common\Cache\ArrayCache;
|
||||
use Doctrine\Common\Cache\Cache as CacheDriver;
|
||||
use Doctrine\Common\Proxy\AbstractProxyFactory;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
use Doctrine\ORM\Cache\CacheConfiguration;
|
||||
use Doctrine\ORM\Mapping\ClassMetadataFactory;
|
||||
use Doctrine\ORM\Mapping\DefaultEntityListenerResolver;
|
||||
@@ -41,6 +42,7 @@ use Doctrine\ORM\Repository\DefaultRepositoryFactory;
|
||||
use Doctrine\ORM\Repository\RepositoryFactory;
|
||||
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use ReflectionClass;
|
||||
|
||||
use function strtolower;
|
||||
@@ -282,23 +284,51 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
/**
|
||||
* Gets the cache driver implementation that is used for metadata caching.
|
||||
*
|
||||
* @deprecated Deprecated in favor of getMetadataCache
|
||||
*
|
||||
* @return CacheDriver|null
|
||||
*/
|
||||
public function getMetadataCacheImpl()
|
||||
{
|
||||
Deprecation::trigger(
|
||||
'doctrine/orm',
|
||||
'https://github.com/doctrine/orm/issues/8650',
|
||||
'Method %s() is deprecated and will be removed in Doctrine ORM 3.0. Use getMetadataCache() instead.',
|
||||
__METHOD__
|
||||
);
|
||||
|
||||
return $this->_attributes['metadataCacheImpl'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cache driver implementation that is used for metadata caching.
|
||||
*
|
||||
* @deprecated Deprecated in favor of setMetadataCache
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setMetadataCacheImpl(CacheDriver $cacheImpl)
|
||||
{
|
||||
Deprecation::trigger(
|
||||
'doctrine/orm',
|
||||
'https://github.com/doctrine/orm/issues/8650',
|
||||
'Method %s() is deprecated and will be removed in Doctrine ORM 3.0. Use setMetadataCache() instead.',
|
||||
__METHOD__
|
||||
);
|
||||
|
||||
$this->_attributes['metadataCacheImpl'] = $cacheImpl;
|
||||
}
|
||||
|
||||
public function getMetadataCache(): ?CacheItemPoolInterface
|
||||
{
|
||||
return $this->_attributes['metadataCache'] ?? null;
|
||||
}
|
||||
|
||||
public function setMetadataCache(CacheItemPoolInterface $cache): void
|
||||
{
|
||||
$this->_attributes['metadataCache'] = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a named DQL query to the configuration.
|
||||
*
|
||||
@@ -387,6 +417,14 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
throw ORMException::queryCacheUsesNonPersistentCache($queryCacheImpl);
|
||||
}
|
||||
|
||||
if ($this->getAutoGenerateProxyClasses()) {
|
||||
throw ORMException::proxyClassesAlwaysRegenerating();
|
||||
}
|
||||
|
||||
if ($this->getMetadataCache()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$metadataCacheImpl = $this->getMetadataCacheImpl();
|
||||
|
||||
if (! $metadataCacheImpl) {
|
||||
@@ -396,10 +434,6 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
if ($metadataCacheImpl instanceof ArrayCache) {
|
||||
throw ORMException::metadataCacheUsesNonPersistentCache($metadataCacheImpl);
|
||||
}
|
||||
|
||||
if ($this->getAutoGenerateProxyClasses()) {
|
||||
throw ORMException::proxyClassesAlwaysRegenerating();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
use BadMethodCallException;
|
||||
use Doctrine\Common\Cache\Psr6\CacheAdapter;
|
||||
use Doctrine\Common\Cache\Psr6\DoctrineProvider;
|
||||
use Doctrine\Common\EventManager;
|
||||
use Doctrine\Common\Util\ClassUtils;
|
||||
use Doctrine\DBAL\Connection;
|
||||
@@ -48,6 +50,7 @@ use function is_callable;
|
||||
use function is_object;
|
||||
use function is_string;
|
||||
use function ltrim;
|
||||
use function method_exists;
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
@@ -164,7 +167,8 @@ use function sprintf;
|
||||
|
||||
$this->metadataFactory = new $metadataFactoryClassName();
|
||||
$this->metadataFactory->setEntityManager($this);
|
||||
$this->metadataFactory->setCacheDriver($this->config->getMetadataCacheImpl());
|
||||
|
||||
$this->configureMetadataCache();
|
||||
|
||||
$this->repositoryFactory = $config->getRepositoryFactory();
|
||||
$this->unitOfWork = new UnitOfWork($this);
|
||||
@@ -986,4 +990,42 @@ use function sprintf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function configureMetadataCache(): void
|
||||
{
|
||||
$metadataCache = $this->config->getMetadataCache();
|
||||
if (! $metadataCache) {
|
||||
$this->configureLegacyMetadataCache();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// We have a PSR-6 compatible metadata factory. Use cache directly
|
||||
if (method_exists($this->metadataFactory, 'setCache')) {
|
||||
$this->metadataFactory->setCache($metadataCache);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Wrap PSR-6 cache to provide doctrine/cache interface
|
||||
$this->metadataFactory->setCacheDriver(DoctrineProvider::wrap($metadataCache));
|
||||
}
|
||||
|
||||
private function configureLegacyMetadataCache(): void
|
||||
{
|
||||
$metadataCache = $this->config->getMetadataCacheImpl();
|
||||
if (! $metadataCache) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Metadata factory is not PSR-6 compatible. Use cache directly
|
||||
if (! method_exists($this->metadataFactory, 'setCache')) {
|
||||
$this->metadataFactory->setCacheDriver($metadataCache);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Wrap doctrine/cache to provide PSR-6 interface
|
||||
$this->metadataFactory->setCache(CacheAdapter::wrap($metadataCache));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,14 +17,16 @@ use Doctrine\ORM\Mapping\QuoteStrategy;
|
||||
use Doctrine\ORM\ORMException;
|
||||
use Doctrine\ORM\Query\ResultSetMapping;
|
||||
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
|
||||
use Doctrine\Tests\DoctrineTestCase;
|
||||
use Doctrine\Tests\Models\DDC753\DDC753CustomRepository;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use ReflectionClass;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
|
||||
/**
|
||||
* Tests for the Configuration object
|
||||
*/
|
||||
class ConfigurationTest extends TestCase
|
||||
class ConfigurationTest extends DoctrineTestCase
|
||||
{
|
||||
/** @var Configuration */
|
||||
private $configuration;
|
||||
@@ -131,6 +133,14 @@ class ConfigurationTest extends TestCase
|
||||
$this->assertSame($queryCacheImpl, $this->configuration->getMetadataCacheImpl());
|
||||
}
|
||||
|
||||
public function testSetGetMetadataCache(): void
|
||||
{
|
||||
$this->assertNull($this->configuration->getMetadataCache());
|
||||
$cache = $this->createStub(CacheItemPoolInterface::class);
|
||||
$this->configuration->setMetadataCache($cache);
|
||||
$this->assertSame($cache, $this->configuration->getMetadataCache());
|
||||
}
|
||||
|
||||
public function testAddGetNamedQuery(): void
|
||||
{
|
||||
$dql = 'SELECT u FROM User u';
|
||||
@@ -182,7 +192,17 @@ class ConfigurationTest extends TestCase
|
||||
$this->addToAssertionCount(1);
|
||||
}
|
||||
|
||||
public function testEnsureProductionSettingsQueryCache(): void
|
||||
public function testEnsureProductionSettingsWithNewMetadataCache(): void
|
||||
{
|
||||
$this->setProductionSettings('metadata');
|
||||
$this->configuration->setMetadataCache(new ArrayAdapter());
|
||||
|
||||
$this->configuration->ensureProductionSettings();
|
||||
|
||||
$this->addToAssertionCount(1);
|
||||
}
|
||||
|
||||
public function testEnsureProductionSettingsMissingQueryCache(): void
|
||||
{
|
||||
$this->setProductionSettings('query');
|
||||
|
||||
@@ -192,7 +212,7 @@ class ConfigurationTest extends TestCase
|
||||
$this->configuration->ensureProductionSettings();
|
||||
}
|
||||
|
||||
public function testEnsureProductionSettingsMetadataCache(): void
|
||||
public function testEnsureProductionSettingsMissingMetadataCache(): void
|
||||
{
|
||||
$this->setProductionSettings('metadata');
|
||||
|
||||
@@ -213,7 +233,7 @@ class ConfigurationTest extends TestCase
|
||||
$this->configuration->ensureProductionSettings();
|
||||
}
|
||||
|
||||
public function testEnsureProductionSettingsMetadataArrayCache(): void
|
||||
public function testEnsureProductionSettingsLegacyMetadataArrayCache(): void
|
||||
{
|
||||
$this->setProductionSettings();
|
||||
$this->configuration->setMetadataCacheImpl(new ArrayCache());
|
||||
|
||||
@@ -13,6 +13,7 @@ use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use GearmanWorker;
|
||||
use InvalidArgumentException;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
|
||||
use function assert;
|
||||
use function is_array;
|
||||
@@ -121,9 +122,9 @@ class LockAgentWorker
|
||||
|
||||
$annotDriver = $config->newDefaultAnnotationDriver([__DIR__ . '/../../../Models/'], true);
|
||||
$config->setMetadataDriverImpl($annotDriver);
|
||||
$config->setMetadataCache(new ArrayAdapter());
|
||||
|
||||
$cache = new ArrayCache();
|
||||
$config->setMetadataCacheImpl($cache);
|
||||
$config->setQueryCacheImpl($cache);
|
||||
$config->setSQLLogger(new EchoSQLLogger());
|
||||
|
||||
|
||||
@@ -21,7 +21,9 @@ use Doctrine\Tests\EventListener\CacheMetadataListener;
|
||||
use Exception;
|
||||
use PHPUnit\Framework\AssertionFailedError;
|
||||
use PHPUnit\Framework\Warning;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
use Throwable;
|
||||
|
||||
use function array_map;
|
||||
@@ -50,9 +52,9 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
|
||||
/**
|
||||
* The metadata cache shared between all functional tests.
|
||||
*
|
||||
* @var Cache|null
|
||||
* @var Cache|CacheItemPoolInterface|null
|
||||
*/
|
||||
private static $_metadataCacheImpl = null;
|
||||
private static $_metadataCache = null;
|
||||
|
||||
/**
|
||||
* The query cache shared between all functional tests.
|
||||
@@ -699,11 +701,11 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
|
||||
// NOTE: Functional tests use their own shared metadata cache, because
|
||||
// the actual database platform used during execution has effect on some
|
||||
// metadata mapping behaviors (like the choice of the ID generation).
|
||||
if (self::$_metadataCacheImpl === null) {
|
||||
if (self::$_metadataCache === null) {
|
||||
if (isset($GLOBALS['DOCTRINE_CACHE_IMPL'])) {
|
||||
self::$_metadataCacheImpl = new $GLOBALS['DOCTRINE_CACHE_IMPL']();
|
||||
self::$_metadataCache = new $GLOBALS['DOCTRINE_CACHE_IMPL']();
|
||||
} else {
|
||||
self::$_metadataCacheImpl = new ArrayCache();
|
||||
self::$_metadataCache = new ArrayAdapter();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -717,7 +719,12 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
|
||||
//FIXME: two different configs! $conn and the created entity manager have
|
||||
// different configs.
|
||||
$config = new Configuration();
|
||||
$config->setMetadataCacheImpl(self::$_metadataCacheImpl);
|
||||
if (self::$_metadataCache instanceof CacheItemPoolInterface) {
|
||||
$config->setMetadataCache(self::$_metadataCache);
|
||||
} else {
|
||||
$config->setMetadataCacheImpl(self::$_metadataCache);
|
||||
}
|
||||
|
||||
$config->setQueryCacheImpl(self::$_queryCacheImpl);
|
||||
$config->setProxyDir(__DIR__ . '/Proxies');
|
||||
$config->setProxyNamespace('Doctrine\Tests\Proxies');
|
||||
|
||||
@@ -17,6 +17,8 @@ use Doctrine\ORM\Cache\Logging\StatisticsCacheLogger;
|
||||
use Doctrine\ORM\Configuration;
|
||||
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
|
||||
use Doctrine\Tests\Mocks\EntityManagerMock;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
|
||||
use function is_array;
|
||||
use function realpath;
|
||||
@@ -29,9 +31,9 @@ abstract class OrmTestCase extends DoctrineTestCase
|
||||
/**
|
||||
* The metadata cache that is shared between all ORM tests (except functional tests).
|
||||
*
|
||||
* @var Cache|null
|
||||
* @var CacheItemPoolInterface|null
|
||||
*/
|
||||
private static $_metadataCacheImpl = null;
|
||||
private static $_metadataCache = null;
|
||||
|
||||
/**
|
||||
* The query cache that is shared between all ORM tests (except functional tests).
|
||||
@@ -92,11 +94,11 @@ abstract class OrmTestCase extends DoctrineTestCase
|
||||
): EntityManagerMock {
|
||||
$metadataCache = $withSharedMetadata
|
||||
? self::getSharedMetadataCacheImpl()
|
||||
: new ArrayCache();
|
||||
: new ArrayAdapter();
|
||||
|
||||
$config = new Configuration();
|
||||
|
||||
$config->setMetadataCacheImpl($metadataCache);
|
||||
$config->setMetadataCache($metadataCache);
|
||||
$config->setMetadataDriverImpl($config->newDefaultAnnotationDriver([], true));
|
||||
$config->setQueryCacheImpl(self::getSharedQueryCacheImpl());
|
||||
$config->setProxyDir(__DIR__ . '/Proxies');
|
||||
@@ -142,13 +144,13 @@ abstract class OrmTestCase extends DoctrineTestCase
|
||||
$this->isSecondLevelCacheLogEnabled = $log;
|
||||
}
|
||||
|
||||
private static function getSharedMetadataCacheImpl(): Cache
|
||||
private static function getSharedMetadataCacheImpl(): ?CacheItemPoolInterface
|
||||
{
|
||||
if (self::$_metadataCacheImpl === null) {
|
||||
self::$_metadataCacheImpl = new ArrayCache();
|
||||
if (self::$_metadataCache === null) {
|
||||
self::$_metadataCache = new ArrayAdapter();
|
||||
}
|
||||
|
||||
return self::$_metadataCacheImpl;
|
||||
return self::$_metadataCache;
|
||||
}
|
||||
|
||||
private static function getSharedQueryCacheImpl(): Cache
|
||||
|
||||
Reference in New Issue
Block a user