diff --git a/lib/Alchemy/Phrasea/Core/Provider/RepositoriesServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/RepositoriesServiceProvider.php index 7995cf8dd2..d4095a1172 100644 --- a/lib/Alchemy/Phrasea/Core/Provider/RepositoriesServiceProvider.php +++ b/lib/Alchemy/Phrasea/Core/Provider/RepositoriesServiceProvider.php @@ -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) { diff --git a/lib/Alchemy/Phrasea/Databox/ArrayCacheDataboxRepository.php b/lib/Alchemy/Phrasea/Databox/ArrayCacheDataboxRepository.php index 75e11a706c..15440ea51b 100644 --- a/lib/Alchemy/Phrasea/Databox/ArrayCacheDataboxRepository.php +++ b/lib/Alchemy/Phrasea/Databox/ArrayCacheDataboxRepository.php @@ -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 = []; + } } diff --git a/lib/Alchemy/Phrasea/Databox/CachingDataboxRepositoryDecorator.php b/lib/Alchemy/Phrasea/Databox/CachingDataboxRepositoryDecorator.php index 5fedad2b8a..1a7d40dca3 100644 --- a/lib/Alchemy/Phrasea/Databox/CachingDataboxRepositoryDecorator.php +++ b/lib/Alchemy/Phrasea/Databox/CachingDataboxRepositoryDecorator.php @@ -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); + } } diff --git a/lib/Alchemy/Phrasea/Databox/DataboxRepository.php b/lib/Alchemy/Phrasea/Databox/DataboxRepository.php index 9740e65698..e784809e95 100644 --- a/lib/Alchemy/Phrasea/Databox/DataboxRepository.php +++ b/lib/Alchemy/Phrasea/Databox/DataboxRepository.php @@ -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); } diff --git a/lib/Alchemy/Phrasea/Databox/DbalDataboxRepository.php b/lib/Alchemy/Phrasea/Databox/DbalDataboxRepository.php index 0346009471..1752df02ed 100644 --- a/lib/Alchemy/Phrasea/Databox/DbalDataboxRepository.php +++ b/lib/Alchemy/Phrasea/Databox/DbalDataboxRepository.php @@ -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()); + + } } diff --git a/lib/classes/databox.php b/lib/classes/databox.php index 582a129674..c0efdce77b 100644 --- a/lib/classes/databox.php +++ b/lib/classes/databox.php @@ -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; }