Move create and mount SQL calls to repository for proper cache invalidation

This commit is contained in:
Thibaud Fabre
2016-01-28 15:53:23 +01:00
parent 2643874b73
commit 40ff41501c
6 changed files with 212 additions and 105 deletions

View File

@@ -145,9 +145,9 @@ class RepositoriesServiceProvider implements ServiceProviderInterface
});
$app['repo.databoxes'] = $app->share(function (PhraseaApplication $app) {
$factory = new DataboxFactory($app);
$appbox = $app->getApplicationBox();
$factory = new DataboxFactory($app);
$repository = new CachingDataboxRepositoryDecorator(
new DbalDataboxRepository($appbox->get_connection(), $factory),
$app['cache'],
@@ -155,9 +155,11 @@ class RepositoriesServiceProvider implements ServiceProviderInterface
$factory
);
$repository = new ArrayCacheDataboxRepository($repository);
$factory->setDataboxRepository($repository);
return new ArrayCacheDataboxRepository($repository);
return $repository;
});
$app['repo.fields.factory'] = $app->protect(function (\databox $databox) use ($app) {

View File

@@ -57,12 +57,46 @@ class ArrayCacheDataboxRepository implements DataboxRepository
*/
public function save(\databox $databox)
{
$this->loaded = false;
$this->databoxes = [];
$this->clear();
return $this->repository->save($databox);
}
/**
* @param $host
* @param $port
* @param $user
* @param $password
* @param $dbname
*
* @return \databox
*/
public function mount($host, $port, $user, $password, $dbname)
{
$this->clear();
return $this->repository->mount($host, $port, $user, $password, $dbname);
}
/**
* @param $host
* @param $port
* @param $user
* @param $password
* @param $dbname
*
* @return \databox
*/
public function create($host, $port, $user, $password, $dbname)
{
$this->clear();
return $this->repository->create($host, $port, $user, $password, $dbname);
}
/**
* Initializes the memory cache if needed.
*/
private function load()
{
if (! $this->loaded) {
@@ -70,4 +104,13 @@ class ArrayCacheDataboxRepository implements DataboxRepository
$this->loaded = true;
}
}
/**
* Clears the memory cache.
*/
private function clear()
{
$this->loaded = false;
$this->databoxes = [];
}
}

View File

@@ -32,7 +32,7 @@ final class CachingDataboxRepositoryDecorator implements DataboxRepository
{
$this->repository = $repository;
$this->cache = $cache;
$this->cacheKey = 'databoxes:' . hash('sha256', $cacheKey);
$this->cacheKey = $cacheKey;
$this->factory = $factory;
}
@@ -64,11 +64,47 @@ final class CachingDataboxRepositoryDecorator implements DataboxRepository
public function save(\databox $databox)
{
$this->cache->delete($this->cacheKey);
$this->clearCache();
return $this->repository->save($databox);
}
/**
* @param $host
* @param $port
* @param $user
* @param $password
* @param $dbname
*
* @return \databox
*/
public function mount($host, $port, $user, $password, $dbname)
{
$databox = $this->repository->mount($host, $port, $user, $password, $dbname);
$this->clearCache();
return $databox;
}
/**
* @param $host
* @param $port
* @param $user
* @param $password
* @param $dbname
*
* @return \databox
*/
public function create($host, $port, $user, $password, $dbname)
{
$databox = $this->repository->create($host, $port, $user, $password, $dbname);
$this->clearCache();
return $databox;
}
/**
* @param \databox[] $databoxes
*/
@@ -82,4 +118,9 @@ final class CachingDataboxRepositoryDecorator implements DataboxRepository
$this->cache->save($this->cacheKey, $rows);
}
private function clearCache()
{
$this->cache->delete($this->cacheKey);
}
}

View File

@@ -26,4 +26,26 @@ interface DataboxRepository
* @param \databox $databox
*/
public function save(\databox $databox);
/**
* @param $host
* @param $port
* @param $user
* @param $password
* @param $dbname
*
* @return \databox
*/
public function mount($host, $port, $user, $password, $dbname);
/**
* @param $host
* @param $port
* @param $user
* @param $password
* @param $dbname
*
* @return \databox
*/
public function create($host, $port, $user, $password, $dbname);
}

View File

@@ -47,6 +47,10 @@ final class DbalDataboxRepository implements DataboxRepository
return $this->factory->createMany($this->fetchRows());
}
/**
* @param \databox $databox
* @return bool
*/
public function save(\databox $databox)
{
return true;
@@ -87,4 +91,73 @@ final class DbalDataboxRepository implements DataboxRepository
return $rows;
}
/**
* @param $host
* @param $port
* @param $user
* @param $password
* @param $dbname
*
* @return \databox
*/
public function mount($host, $port, $user, $password, $dbname)
{
$query = 'INSERT INTO sbas (ord, host, port, dbname, sqlengine, user, pwd)
SELECT COALESCE(MAX(ord), 0) + 1 AS ord, :host AS host, :port AS port, :dbname AS dbname,
"MYSQL" AS sqlengine, :user AS user, :password AS pwd FROM sbas';
$statement = $this->connection->prepare($query);
$statement->execute([
':host' => $host,
':port' => $port,
':dbname' => $dbname,
':user' => $user,
':password' => $password
]);
$statement->closeCursor();
return $this->find((int) $this->connection->lastInsertId());
}
/**
* @param $host
* @param $port
* @param $user
* @param $password
* @param $dbname
*
* @return \databox
*/
public function create($host, $port, $user, $password, $dbname)
{
$params = [
':host' => $host,
':port' => $port,
':user' => $user,
':password' => $password,
':dbname' => $dbname
];
$query = 'SELECT sbas_id FROM sbas
WHERE host = :host AND port = :port AND `user` = :user AND pwd = :password AND dbname = :dbname';
$statement = $this->connection->executeQuery($query, $params);
if ($row = $statement->fetch(\PDO::FETCH_ASSOC)) {
return $this->find((int) $row['sbas_id']);
}
$query = 'INSERT INTO sbas (ord, host, port, dbname, sqlengine, user, pwd)
SELECT COALESCE(MAX(ord), 0) + 1 AS ord, :host AS host, :port AS port, :dbname AS dbname,
"MYSQL" AS sqlengine, :user AS user, :password AS pwd FROM sbas';
$stmt = $this->connection->prepare($query);
$stmt->execute($params);
$stmt->closeCursor();
return $this->find((int) $this->connection->lastInsertId());
}
}

View File

@@ -62,51 +62,28 @@ class databox extends base implements ThumbnailedElement
/**
* @param Application $app
* @param Connection $connection
* @param Connection $databoxConnection
* @param SplFileInfo $data_template
* @return databox
* @throws \Doctrine\DBAL\DBALException
*/
public static function create(Application $app, Connection $connection, \SplFileInfo $data_template)
public static function create(Application $app, Connection $databoxConnection, \SplFileInfo $data_template)
{
if ( ! file_exists($data_template->getRealPath())) {
throw new \InvalidArgumentException($data_template->getRealPath() . " does not exist");
}
$sql = 'SELECT sbas_id
FROM sbas
WHERE host = :host AND port = :port AND dbname = :dbname
AND user = :user AND pwd = :password';
$host = $databoxConnection->getHost();
$port = $databoxConnection->getPort();
$dbname = $databoxConnection->getDatabase();
$user = $databoxConnection->getUsername();
$password = $databoxConnection->getPassword();
$host = $connection->getHost();
$port = $connection->getPort();
$dbname = $connection->getDatabase();
$user = $connection->getUsername();
$password = $connection->getPassword();
$params = [
':host' => $host,
':port' => $port,
':dbname' => $dbname,
':user' => $user,
':password' => $password
];
/** @var appbox $appbox */
$appbox = $app['phraseanet.appbox'];
$stmt = $appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if ($row) {
return $appbox->get_databox((int) $row['sbas_id']);
}
$appbox = $app->getApplicationBox();
try {
$sql = 'CREATE DATABASE `' . $dbname . '`
CHARACTER SET utf8 COLLATE utf8_unicode_ci';
$stmt = $connection->prepare($sql);
$sql = 'CREATE DATABASE `' . $dbname . '` CHARACTER SET utf8 COLLATE utf8_unicode_ci';
$stmt = $databoxConnection->prepare($sql);
$stmt->execute();
$stmt->closeCursor();
} catch (\Exception $e) {
@@ -114,29 +91,10 @@ class databox extends base implements ThumbnailedElement
}
$sql = 'USE `' . $dbname . '`';
$stmt = $connection->prepare($sql);
$stmt = $databoxConnection->prepare($sql);
$stmt->execute();
$stmt->closeCursor();
$sql = 'SELECT MAX(ord) as ord FROM sbas';
$stmt = $appbox->get_connection()->prepare($sql);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if ($row) {
$ord = $row['ord'] + 1;
}
$params[':ord'] = $ord;
$sql = 'INSERT INTO sbas (sbas_id, ord, host, port, dbname, sqlengine, user, pwd)
VALUES (null, :ord, :host, :port, :dbname, "MYSQL", :user, :password)';
$stmt = $appbox->get_connection()->prepare($sql);
$stmt->execute($params);
$stmt->closeCursor();
$sbas_id = (int) $appbox->get_connection()->lastInsertId();
$app['orm.add']([
'host' => $host,
'port' => $port,
@@ -145,21 +103,20 @@ class databox extends base implements ThumbnailedElement
'password' => $password
]);
phrasea::reset_sbasDatas($app['phraseanet.appbox']);
/** @var DataboxRepository $databoxRepository */
$databoxRepository = $app['repo.databoxes'];
$databox = $databoxRepository->create($host, $port, $user, $password, $dbname);
$appbox->delete_data_from_cache(appbox::CACHE_LIST_BASES);
$databox = $appbox->get_databox($sbas_id);
$databox->insert_datas();
$databox->setNewStructure(
$data_template, $app['conf']->get(['main', 'storage', 'subdefs'])
);
$app['dispatcher']->dispatch(
DataboxEvents::CREATED,
new CreatedEvent(
$databox
)
);
$app['dispatcher']->dispatch(DataboxEvents::CREATED, new CreatedEvent($databox));
return $databox;
}
@@ -176,56 +133,25 @@ class databox extends base implements ThumbnailedElement
*/
public static function mount(Application $app, $host, $port, $user, $password, $dbname)
{
$conn = $app['db.provider']([
$app['db.provider']([
'host' => $host,
'port' => $port,
'user' => $user,
'password' => $password,
'dbname' => $dbname,
]);
])->connect();
$conn->connect();
$conn = $app->getApplicationBox()->get_connection();
$sql = 'SELECT MAX(ord) as ord FROM sbas';
$stmt = $conn->prepare($sql);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if ($row)
$ord = $row['ord'] + 1;
$sql = 'INSERT INTO sbas (sbas_id, ord, host, port, dbname, sqlengine, user, pwd)
VALUES (null, :ord, :host, :port, :dbname, "MYSQL", :user, :password)';
$stmt = $conn->prepare($sql);
$stmt->execute([
':ord' => $ord,
':host' => $host,
':port' => $port,
':dbname' => $dbname,
':user' => $user,
':password' => $password
]);
$stmt->closeCursor();
$sbas_id = (int) $conn->lastInsertId();
$app->getApplicationBox()->delete_data_from_cache(appbox::CACHE_LIST_BASES);
$databox = $app->findDataboxById($sbas_id);
/** @var DataboxRepository $databoxRepository */
$databoxRepository = $app['repo.databoxes'];
$databox = $databoxRepository->mount($host, $port, $user, $password, $dbname);
$databox->delete_data_from_cache(databox::CACHE_COLLECTIONS);
$app->getApplicationBox()->delete_data_from_cache(appbox::CACHE_LIST_BASES);
phrasea::reset_sbasDatas($app['phraseanet.appbox']);
cache_databox::update($app, $databox->get_sbas_id(), 'structure');
$app['dispatcher']->dispatch(
DataboxEvents::MOUNTED,
new MountedEvent(
$databox
)
);
$app['dispatcher']->dispatch(DataboxEvents::MOUNTED, new MountedEvent($databox));
return $databox;
}