Skip to content

Commit

Permalink
Started refactoring the ORM Cache Shell
Browse files Browse the repository at this point in the history
  • Loading branch information
burzum committed Aug 1, 2017
1 parent 6cbfdab commit b0d7c67
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 55 deletions.
115 changes: 115 additions & 0 deletions src/ORM/OrmCache.php
@@ -0,0 +1,115 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 3.0.0
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Orm;

use Cake\Cache\Cache;
use Cake\Datasource\ConnectionManager;

/**
* ORM Cache.
*
* This tool is intended to be used by deployment scripts so that you
* can prevent thundering herd effects on the metadata cache when new
* versions of your application are deployed, or when migrations
* requiring updated metadata are required.
*/
class OrmCache
{

/**
* Schema
*
* @var \Cake\Datasource\SchemaInterface
*/
protected $_schema;

/**
* Constructor
*
* @param string $connection Connection name
*/
public function __construct($connection)
{
$this->_schema = $this->getSchema($connection);
}

/**
* Build metadata.
*
* @param string|null $name The name of the table to build cache data for.
* @return bool
*/
public function build($name = null)
{
$tables = [$name];
if (empty($name)) {
$tables = $this->_schema->listTables();
}

foreach ($tables as $table) {
$this->_schema->describe($table, ['forceRefresh' => true]);
}

return true;
}

/**
* Clear metadata.
*
* @param string|null $name The name of the table to clear cache data for.
* @return bool
*/
public function clear($name = null)
{
$tables = [$name];
if (empty($name)) {
$tables = $this->_schema->listTables();
}
$configName = $this->_schema->getCacheMetadata();

foreach ($tables as $table) {
$key = $this->_schema->cacheKey($table);
Cache::delete($key, $configName);
}

return true;
}

/**
* Helper method to get the schema collection.
*
* @param string $connection Connection name to get the schema for
* @return false|\Cake\Database\Schema\Collection|\Cake\Database\Schema\CachedCollection
*/
public function getSchema($connection)
{
/* @var \Cake\Database\Connection $source */
$source = ConnectionManager::get($connection);
if (!method_exists($source, 'schemaCollection')) {
throw new RuntimeException(sprintf(
'The "%s" connection is not compatible with orm caching, ' .
'as it does not implement a "schemaCollection()" method.',
$connection
));
}

$config = $source->config();
if (empty($config['cacheMetadata'])) {
$source->cacheMetadata(true);
}

return $source->getSchemaCollection();
}
}
74 changes: 21 additions & 53 deletions src/Shell/OrmCacheShell.php
Expand Up @@ -14,9 +14,9 @@
*/
namespace Cake\Shell;

use Cake\Cache\Cache;
use Cake\Console\Shell;
use Cake\Datasource\ConnectionManager;
use Cake\Orm\OrmCache;
use RuntimeException;

/**
* ORM Cache Shell.
Expand All @@ -30,6 +30,13 @@
class OrmCacheShell extends Shell
{

/**
* ORM Cache
*
* @var \Cake\ORM\OrmCache
*/
protected $_ormCache;

/**
* Build metadata.
*
Expand All @@ -38,18 +45,9 @@ class OrmCacheShell extends Shell
*/
public function build($name = null)
{
$schema = $this->_getSchema();
if (!$schema) {
return false;
}
$tables = [$name];
if (empty($name)) {
$tables = $schema->listTables();
}
foreach ($tables as $table) {
$this->_io->verbose('Building metadata cache for ' . $table);
$schema->describe($table, ['forceRefresh' => true]);
}
$cache = $this->_getOrmCache();
$cache->build($name);

$this->out('<success>Cache build complete</success>');

return true;
Expand All @@ -63,56 +61,26 @@ public function build($name = null)
*/
public function clear($name = null)
{
$schema = $this->_getSchema();
if (!$schema) {
return false;
}
$tables = [$name];
if (empty($name)) {
$tables = $schema->listTables();
}
$configName = $schema->getCacheMetadata();
$cache = $this->_getOrmCache();
$cache->clear($name);

foreach ($tables as $table) {
$this->_io->verbose(sprintf(
'Clearing metadata cache from "%s" for %s',
$configName,
$table
));
$key = $schema->cacheKey($table);
Cache::delete($key, $configName);
}
$this->out('<success>Cache clear complete</success>');

return true;
}

/**
* Helper method to get the schema collection.
* Gets the ORM Cache instance
*
* @return false|\Cake\Database\Schema\Collection|\Cake\Database\Schema\CachedCollection
* @return \Cake\ORM\OrmCache
*/
protected function _getSchema()
protected function _getOrmCache()
{
/* @var \Cake\Database\Connection $source */
$source = ConnectionManager::get($this->params['connection']);
if (!method_exists($source, 'schemaCollection')) {
$msg = sprintf(
'The "%s" connection is not compatible with orm caching, ' .
'as it does not implement a "schemaCollection()" method.',
$this->params['connection']
);
$this->abort($msg);

return false;
}
$config = $source->config();
if (empty($config['cacheMetadata'])) {
$this->_io->verbose('Metadata cache was disabled in config. Enabling to clear cache.');
$source->cacheMetadata(true);
try {
return new OrmCache($this->params['connection']);
} catch (RuntimeException $e) {
$this->abort($e->getMessage());
}

return $source->getSchemaCollection();
}

/**
Expand Down
4 changes: 2 additions & 2 deletions tests/TestCase/Shell/OrmCacheShellTest.php
Expand Up @@ -151,7 +151,7 @@ public function testBuildOverwritesExistingData()
/**
* Test build() with a non-existing connection name.
*
* @expectedException \Cake\Datasource\Exception\MissingDatasourceConfigException
* @expectedException \Cake\Console\Exception\StopException
* @return void
*/
public function testBuildInvalidConnection()
Expand All @@ -163,7 +163,7 @@ public function testBuildInvalidConnection()
/**
* Test clear() with an invalid connection name.
*
* @expectedException \Cake\Datasource\Exception\MissingDatasourceConfigException
* @expectedException \Cake\Console\Exception\StopException
* @return void
*/
public function testClearInvalidConnection()
Expand Down

0 comments on commit b0d7c67

Please sign in to comment.