ENH store tableList in cache (#11183)

This commit is contained in:
Thomas Portelange 2024-03-26 00:03:46 +01:00 committed by GitHub
parent 164e2a18ab
commit 492cb800fa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 14 deletions

View File

@ -46,3 +46,8 @@ SilverStripe\Core\Injector\Injector:
factory: SilverStripe\Core\Cache\CacheFactory
constructor:
namespace: 'VersionProvider'
Psr\SimpleCache\CacheInterface.ClassInfo:
factory: SilverStripe\Core\Cache\CacheFactory
constructor:
namespace: "ClassInfo"
disable-container: true

View File

@ -10,6 +10,9 @@ use SilverStripe\Core\Manifest\ClassLoader;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DB;
use SilverStripe\View\ViewableData;
use Psr\SimpleCache\CacheInterface;
use SilverStripe\Core\Flushable;
use SilverStripe\Core\Injector\Injector;
/**
* Provides introspection information about the class tree.
@ -18,16 +21,8 @@ use SilverStripe\View\ViewableData;
* class introspection heavily and without the caching it creates an unfortunate
* performance hit.
*/
class ClassInfo
class ClassInfo implements Flushable
{
/**
* Cache for {@link hasTable()}
*
* @internal
* @var array
*/
private static $_cache_all_tables = [];
/**
* @internal
* @var array Cache for {@link ancestry()}.
@ -82,24 +77,41 @@ class ClassInfo
}
/**
* Cached call to see if the table exists in the DB.
* For live queries, use DBSchemaManager::hasTable.
* @param string $tableName
* @return bool
*/
public static function hasTable($tableName)
{
// Cache the list of all table names to reduce on DB traffic
if (empty(self::$_cache_all_tables) && DB::is_active()) {
self::$_cache_all_tables = DB::get_schema()->tableList();
$cache = self::getCache();
$configData = serialize(DB::getConfig());
$cacheKey = 'tableList_' . md5($configData);
$tableList = $cache->get($cacheKey) ?? [];
if (empty($tableList) && DB::is_active()) {
$tableList = DB::get_schema()->tableList();
// Cache the list of all table names to reduce on DB traffic
$cache->set($cacheKey, $tableList);
}
return !empty(self::$_cache_all_tables[strtolower($tableName)]);
return !empty($tableList[strtolower($tableName)]);
}
private static function getCache(): CacheInterface
{
return Injector::inst()->get(CacheInterface::class . '.ClassInfo');
}
public static function reset_db_cache()
{
self::$_cache_all_tables = null;
self::getCache()->clear();
self::$_cache_ancestry = [];
}
public static function flush()
{
self::reset_db_cache();
}
/**
* Returns the manifest of all classes which are present in the database.
*