Skip to content

Commit

Permalink
ENH store tableList in cache (silverstripe#11183)
Browse files Browse the repository at this point in the history
  • Loading branch information
lekoala authored Mar 25, 2024
1 parent 164e2a1 commit 492cb80
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 14 deletions.
5 changes: 5 additions & 0 deletions _config/cache.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
40 changes: 26 additions & 14 deletions src/Core/ClassInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
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.
Expand All @@ -18,16 +21,8 @@
* 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()}.
Expand Down Expand Up @@ -82,24 +77,41 @@ public static function exists($class)
}

/**
* 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.
*
Expand Down

0 comments on commit 492cb80

Please sign in to comment.