-
Notifications
You must be signed in to change notification settings - Fork 180
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Separate db tool and db backup/restore services for version 2.x
- Loading branch information
1 parent
acaaadf
commit 02e3518
Showing
19 changed files
with
1,062 additions
and
339 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
<?xml version="1.0" ?> | ||
|
||
<container xmlns="http://symfony.com/schema/dic/services" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> | ||
|
||
<services> | ||
<service id="liip_functional_test.services.fixtures_loader_factory" class="Liip\FunctionalTestBundle\Services\FixturesLoaderFactory" public="true"> | ||
<argument type="service" id="service_container" /> | ||
</service> | ||
|
||
<service id="liip_functional_test.services_database_backup.sqlite" class="Liip\FunctionalTestBundle\Services\DatabaseBackup\SqliteDatabaseBackup" public="true"> | ||
<argument type="service" id="service_container" /> | ||
<argument type="service" id="liip_functional_test.services.fixtures_loader_factory" /> | ||
</service> | ||
|
||
<service id="liip_functional_test.services_database_backup.mysql_custom" class="Liip\FunctionalTestBundle\Services\DatabaseBackup\MysqlCustomDatabaseBackup" public="true"> | ||
<argument type="service" id="service_container" /> | ||
<argument type="service" id="liip_functional_test.services.fixtures_loader_factory" /> | ||
</service> | ||
|
||
<service id="liip_functional_test.services_database_tools.ormdatabase_tool" class="Liip\FunctionalTestBundle\Services\DatabaseTools\ORMDatabaseTool" public="false"> | ||
<argument type="service" id="service_container" /> | ||
<argument type="service" id="liip_functional_test.services.fixtures_loader_factory" /> | ||
</service> | ||
<service id="liip_functional_test.services_database_tools.ormsqllite_database_tool" class="Liip\FunctionalTestBundle\Services\DatabaseTools\ORMSqlliteDatabaseTool" public="false"> | ||
<argument type="service" id="service_container" /> | ||
<argument type="service" id="liip_functional_test.services.fixtures_loader_factory" /> | ||
</service> | ||
<service id="liip_functional_test.services_database_tools.mongo_dbdatabase_tool" class="Liip\FunctionalTestBundle\Services\DatabaseTools\MongoDBDatabaseTool" public="false"> | ||
<argument type="service" id="service_container" /> | ||
<argument type="service" id="liip_functional_test.services.fixtures_loader_factory" /> | ||
</service> | ||
<service id="liip_functional_test.services_database_tools.phpcrdatabase_tool" class="Liip\FunctionalTestBundle\Services\DatabaseTools\PHPCRDatabaseTool" public="false"> | ||
<argument type="service" id="service_container" /> | ||
<argument type="service" id="liip_functional_test.services.fixtures_loader_factory" /> | ||
</service> | ||
<service id="liip_functional_test.services.database_tool_collection" class="Liip\FunctionalTestBundle\Services\DatabaseToolCollection" public="true"> | ||
<argument type="service" id="service_container" /> | ||
<argument type="service" id="liip_functional_test.services.fixtures_loader_factory" /> | ||
<call method="add"> | ||
<argument type="service" id="liip_functional_test.services_database_tools.ormdatabase_tool" /> | ||
</call> | ||
<call method="add"> | ||
<argument type="service" id="liip_functional_test.services_database_tools.ormsqllite_database_tool" /> | ||
</call> | ||
<call method="add"> | ||
<argument type="service" id="liip_functional_test.services_database_tools.mongo_dbdatabase_tool" /> | ||
</call> | ||
<call method="add"> | ||
<argument type="service" id="liip_functional_test.services_database_tools.phpcrdatabase_tool" /> | ||
</call> | ||
</service> | ||
</services> | ||
</container> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Liip/FunctionalTestBundle | ||
* | ||
* (c) Lukas Kahwe Smith <[email protected]> | ||
* | ||
* This source file is subject to the MIT license that is bundled | ||
* with this source code in the file LICENSE. | ||
*/ | ||
|
||
namespace Liip\FunctionalTestBundle\Services\DatabaseBackup; | ||
|
||
use Doctrine\Common\DataFixtures\Executor\AbstractExecutor; | ||
use Doctrine\DBAL\Connection; | ||
use Liip\FunctionalTestBundle\Services\FixturesLoaderFactory; | ||
use Symfony\Component\DependencyInjection\ContainerInterface; | ||
|
||
/** | ||
* @author Aleksey Tupichenkov <[email protected]> | ||
*/ | ||
abstract class AbstractDatabaseBackup | ||
{ | ||
protected $container; | ||
protected $fixturesLoaderFactory; | ||
|
||
/** | ||
* @var Connection | ||
*/ | ||
protected $connection; | ||
|
||
/** | ||
* @var array | ||
*/ | ||
protected $metadatas; | ||
|
||
/** | ||
* The fixture classnames. | ||
* | ||
* @var array | ||
*/ | ||
protected $classNames; | ||
|
||
public function __construct(ContainerInterface $container, FixturesLoaderFactory $fixturesLoaderFactory) | ||
{ | ||
$this->container = $container; | ||
$this->fixturesLoaderFactory = $fixturesLoaderFactory; | ||
} | ||
|
||
public function init(Connection $connection, array $metadatas, array $classNames): void | ||
{ | ||
$this->connection = $connection; | ||
$this->metadatas = $metadatas; | ||
$this->classNames = $classNames; | ||
} | ||
|
||
abstract public function getBackupName(): string; | ||
|
||
abstract public function isBackupActual(): bool; | ||
|
||
abstract public function backup(AbstractExecutor $executor): void; | ||
|
||
abstract public function restore(AbstractExecutor $executor): void; | ||
|
||
/** | ||
* Determine if the Fixtures that define a database backup have been | ||
* modified since the backup was made. | ||
* | ||
* @param string $backup The fixture backup SQLite database file path | ||
* | ||
* @return bool TRUE if the backup was made since the modifications to the | ||
* fixtures; FALSE otherwise | ||
*/ | ||
protected function isBackupUpToDate(string $backup): bool | ||
{ | ||
$backupLastModifiedDateTime = \DateTime::createFromFormat('U', filemtime($backup)); | ||
|
||
$loader = $this->fixturesLoaderFactory->getFixtureLoader($this->classNames); | ||
|
||
// Use loader in order to fetch all the dependencies fixtures. | ||
foreach ($loader->getFixtures() as $className) { | ||
$fixtureLastModifiedDateTime = $this->getFixtureLastModified($className); | ||
if ($backupLastModifiedDateTime < $fixtureLastModifiedDateTime) { | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
/** | ||
* This function finds the time when the data blocks of a class definition | ||
* file were being written to, that is, the time when the content of the | ||
* file was changed. | ||
* | ||
* @param string $class The fully qualified class name of the fixture class to | ||
* check modification date on | ||
* | ||
* @return \DateTime|null | ||
*/ | ||
protected function getFixtureLastModified($class): ?\DateTime | ||
{ | ||
$lastModifiedDateTime = null; | ||
|
||
$reflClass = new \ReflectionClass($class); | ||
$classFileName = $reflClass->getFileName(); | ||
|
||
if (file_exists($classFileName)) { | ||
$lastModifiedDateTime = new \DateTime(); | ||
$lastModifiedDateTime->setTimestamp(filemtime($classFileName)); | ||
} | ||
|
||
return $lastModifiedDateTime; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Liip/FunctionalTestBundle | ||
* | ||
* (c) Lukas Kahwe Smith <[email protected]> | ||
* | ||
* This source file is subject to the MIT license that is bundled | ||
* with this source code in the file LICENSE. | ||
*/ | ||
|
||
namespace Liip\FunctionalTestBundle\Services\DatabaseBackup; | ||
|
||
use Doctrine\Common\DataFixtures\Executor\AbstractExecutor; | ||
|
||
/** | ||
* @author Aleksey Tupichenkov <[email protected]> | ||
* | ||
* It's class created just for example that how to create database backup/restore service | ||
*/ | ||
class MysqlCustomDatabaseBackup extends AbstractDatabaseBackup | ||
{ | ||
public function getBackupName(): string | ||
{ | ||
return $this->container->getParameter('kernel.cache_dir').'/test_mysql_'.md5(serialize($this->metadatas).serialize($this->classNames)).'.sql'; | ||
} | ||
|
||
public function isBackupActual(): bool | ||
{ | ||
$backupDBFileName = $this->getBackupName(); | ||
$backupReferenceFileName = $backupDBFileName.'.ser'; | ||
|
||
return file_exists($backupDBFileName) && file_exists($backupReferenceFileName) && $this->isBackupUpToDate($backupDBFileName); | ||
} | ||
|
||
public function backup(AbstractExecutor $executor): void | ||
{ | ||
$params = $this->connection->getParams(); | ||
if (isset($params['master'])) { | ||
$params = $params['master']; | ||
} | ||
|
||
$dbName = isset($params['dbname']) ? $params['dbname'] : ''; | ||
$dbHost = isset($params['host']) ? $params['host'] : ''; | ||
$dbPort = isset($params['port']) ? $params['port'] : ''; | ||
$dbUser = isset($params['user']) ? $params['user'] : ''; | ||
$dbPass = isset($params['password']) ? $params['password'] : ''; | ||
|
||
$executor->getReferenceRepository()->save($this->getBackupName()); | ||
|
||
exec("mysqldump -h $dbHost -u $dbUser -p$dbPass $dbName > {$this->getBackupName()}"); | ||
} | ||
|
||
public function restore(AbstractExecutor $executor): void | ||
{ | ||
$params = $this->connection->getParams(); | ||
if (isset($params['master'])) { | ||
$params = $params['master']; | ||
} | ||
|
||
$dbName = isset($params['dbname']) ? $params['dbname'] : ''; | ||
$dbHost = isset($params['host']) ? $params['host'] : ''; | ||
$dbPort = isset($params['port']) ? $params['port'] : ''; | ||
$dbUser = isset($params['user']) ? $params['user'] : ''; | ||
$dbPass = isset($params['password']) ? $params['password'] : ''; | ||
|
||
exec("mysqladmin -h $dbHost -u $dbUser -p$dbPass drop $dbName -f"); | ||
exec("mysqladmin -h $dbHost -u $dbUser -p$dbPass create $dbName"); | ||
exec("mysql -h $dbHost -u $dbUser -p$dbPass $dbName < {$this->getBackupName()}"); | ||
|
||
$executor->getReferenceRepository()->load($this->getBackupName()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Liip/FunctionalTestBundle | ||
* | ||
* (c) Lukas Kahwe Smith <[email protected]> | ||
* | ||
* This source file is subject to the MIT license that is bundled | ||
* with this source code in the file LICENSE. | ||
*/ | ||
|
||
namespace Liip\FunctionalTestBundle\Services\DatabaseBackup; | ||
|
||
use Doctrine\Common\DataFixtures\Executor\AbstractExecutor; | ||
|
||
/** | ||
* @author Aleksey Tupichenkov <[email protected]> | ||
*/ | ||
class SqliteDatabaseBackup extends AbstractDatabaseBackup | ||
{ | ||
public function getBackupName(): string | ||
{ | ||
return $this->container->getParameter('kernel.cache_dir').'/test_sqllite_'.md5(serialize($this->metadatas).serialize($this->classNames)).'.db'; | ||
} | ||
|
||
private function getDatabaseName(): string | ||
{ | ||
$params = $this->connection->getParams(); | ||
if (isset($params['master'])) { | ||
$params = $params['master']; | ||
} | ||
|
||
$name = $params['path'] ?? ($params['dbname'] ?? false); | ||
if (!$name) { | ||
throw new \InvalidArgumentException("Connection does not contain a 'path' or 'dbname' parameter and cannot be dropped."); | ||
} | ||
|
||
return $name; | ||
} | ||
|
||
public function isBackupActual(): bool | ||
{ | ||
$backupDBFileName = $this->getBackupName(); | ||
$backupReferenceFileName = $backupDBFileName.'.ser'; | ||
|
||
return file_exists($backupDBFileName) && file_exists($backupReferenceFileName) && $this->isBackupUpToDate($backupDBFileName); | ||
} | ||
|
||
public function backup(AbstractExecutor $executor): void | ||
{ | ||
$executor->getReferenceRepository()->save($this->getBackupName()); | ||
copy($this->getDatabaseName(), $this->getBackupName()); | ||
} | ||
|
||
public function restore(AbstractExecutor $executor): void | ||
{ | ||
copy($this->getBackupName(), $this->getDatabaseName()); | ||
$executor->getReferenceRepository()->load($this->getBackupName()); | ||
} | ||
} |
Oops, something went wrong.