Commit 3678b651 authored by beberlei's avatar beberlei

[2.0] DDC-114 - Extend SchemaTool Drop functionality to optionally drop the...

[2.0] DDC-114 - Extend SchemaTool Drop functionality to optionally drop the complete database. Additionally a filter against all existing table is applied to avoid errors due to dropping non-existant tables. Updated Schema-Tool CLI command with optional calls --drop=database --drop=metadata but kept original --drop which defaults to "metadata". Updated documentation.
parent 884131e5
...@@ -60,8 +60,9 @@ class SchemaToolTask extends AbstractTask ...@@ -60,8 +60,9 @@ class SchemaToolTask extends AbstractTask
->writeln("\t\tCreates the schema in EntityManager (create tables on Database)") ->writeln("\t\tCreates the schema in EntityManager (create tables on Database)")
->writeln("\t\t\tIf defined, --drop and --update can not be requested on same task") ->writeln("\t\t\tIf defined, --drop and --update can not be requested on same task")
->write(PHP_EOL) ->write(PHP_EOL)
->write('--drop', 'REQ_ARG') ->write('--drop=<metadata|database>', 'REQ_ARG')
->writeln("\t\t\tDrops the schema of EntityManager (drop tables on Database)") ->writeln("\t\t\tDrops the schema of EntityManager (drop tables on Database)")
->writeln("\t\t\tDefaults to 'metadata' if only --drop is specified.")
->writeln("\t\t\tIf defined, --create and --update can not be requested on same task") ->writeln("\t\t\tIf defined, --create and --update can not be requested on same task")
->write(PHP_EOL) ->write(PHP_EOL)
->write('--update', 'REQ_ARG') ->write('--update', 'REQ_ARG')
...@@ -90,7 +91,7 @@ class SchemaToolTask extends AbstractTask ...@@ -90,7 +91,7 @@ class SchemaToolTask extends AbstractTask
private function _writeSynopsis($printer) private function _writeSynopsis($printer)
{ {
$printer->write('schema-tool', 'KEYWORD') $printer->write('schema-tool', 'KEYWORD')
->write(' (--create | --drop | --update | --re-create)', 'REQ_ARG') ->write(' (--create | --drop=<metadata|database> | --update | --re-create)', 'REQ_ARG')
->writeln(' [--dump-sql] [--class-dir=<path>]', 'OPT_ARG'); ->writeln(' [--dump-sql] [--class-dir=<path>]', 'OPT_ARG');
} }
...@@ -169,15 +170,20 @@ class SchemaToolTask extends AbstractTask ...@@ -169,15 +170,20 @@ class SchemaToolTask extends AbstractTask
$tool = new SchemaTool($em); $tool = new SchemaTool($em);
if ($isDrop) { if ($isDrop) {
$dropMode = $args['drop'];
if(!in_array($dropMode, array('metadata', 'database'))) {
$dropMode = 'metadata';
}
if (isset($args['dump-sql'])) { if (isset($args['dump-sql'])) {
foreach ($tool->getDropSchemaSql($classes) as $sql) { foreach ($tool->getDropSchemaSql($classes, $dropMode) as $sql) {
$printer->writeln($sql); $printer->writeln($sql);
} }
} else { } else {
$printer->writeln('Dropping database schema...', 'INFO'); $printer->writeln('Dropping database schema...', 'INFO');
try { try {
$tool->dropSchema($classes); $tool->dropSchema($classes, $dropMode);
$printer->writeln('Database schema dropped successfully.', 'INFO'); $printer->writeln('Database schema dropped successfully.', 'INFO');
} catch (\Exception $ex) { } catch (\Exception $ex) {
throw new DoctrineException($ex); throw new DoctrineException($ex);
......
...@@ -40,6 +40,15 @@ use Doctrine\DBAL\Types\Type, ...@@ -40,6 +40,15 @@ use Doctrine\DBAL\Types\Type,
*/ */
class SchemaTool class SchemaTool
{ {
/**
* @var string
*/
const DROP_METADATA = "metadata";
/**
* @var string
*/
const DROP_DATABASE = "database";
/** /**
* @var \Doctrine\ORM\EntityManager * @var \Doctrine\ORM\EntityManager
*/ */
...@@ -418,12 +427,16 @@ class SchemaTool ...@@ -418,12 +427,16 @@ class SchemaTool
/** /**
* Drops the database schema for the given classes. * Drops the database schema for the given classes.
* *
* In any way when an exception is thrown it is supressed since drop was
* issued for all classes of the schema and some probably just don't exist.
*
* @param array $classes * @param array $classes
* @param string $mode
* @return void * @return void
*/ */
public function dropSchema(array $classes) public function dropSchema(array $classes, $mode=self::DROP_METADATA)
{ {
$dropSchemaSql = $this->getDropSchemaSql($classes); $dropSchemaSql = $this->getDropSchemaSql($classes, $mode);
$conn = $this->_em->getConnection(); $conn = $this->_em->getConnection();
foreach ($dropSchemaSql as $sql) { foreach ($dropSchemaSql as $sql) {
...@@ -435,18 +448,67 @@ class SchemaTool ...@@ -435,18 +448,67 @@ class SchemaTool
* Gets the SQL needed to drop the database schema for the given classes. * Gets the SQL needed to drop the database schema for the given classes.
* *
* @param array $classes * @param array $classes
* @param string $mode
* @return array * @return array
*/ */
public function getDropSchemaSql(array $classes) public function getDropSchemaSql(array $classes, $mode=self::DROP_METADATA)
{ {
if($mode == self::DROP_METADATA) {
$tables = $this->_getDropSchemaTablesMetadataMode($classes);
} else if($mode == self::DROP_DATABASE) {
$tables = $this->_getDropSchemaTablesDatabaseMode($classes);
} else {
throw new \Doctrine\ORM\ORMException("Given Drop Schema Mode is not supported.");
}
$sm = $this->_em->getConnection()->getSchemaManager();
/* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */
$allTables = $sm->listTables();
$sql = array(); $sql = array();
foreach($tables AS $tableName) {
if(in_array($tableName, $allTables)) {
$sql[] = $this->_platform->getDropTableSql($tableName);
}
}
return $sql;
}
/**
* Drop all tables of the database connection.
*
* @return array
*/
private function _getDropSchemaTablesDatabaseMode($classes)
{
$conn = $this->_em->getConnection();
$sm = $conn->getSchemaManager();
/* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */
$allTables = $sm->listTables();
$orderedTables = $this->_getDropSchemaTablesMetadataMode($classes);
foreach($allTables AS $tableName) {
if(!in_array($tableName, $orderedTables)) {
$orderedTables[] = $tableName;
}
}
return $orderedTables;
}
private function _getDropSchemaTablesMetadataMode(array $classes)
{
$orderedTables = array();
$commitOrder = $this->_getCommitOrder($classes); $commitOrder = $this->_getCommitOrder($classes);
$associationTables = $this->_getAssociationTables($commitOrder); $associationTables = $this->_getAssociationTables($commitOrder);
// Drop association tables first // Drop association tables first
foreach ($associationTables as $associationTable) { foreach ($associationTables as $associationTable) {
$sql[] = $this->_platform->getDropTableSql($associationTable); $orderedTables[] = $associationTable;
} }
// Drop tables in reverse commit order // Drop tables in reverse commit order
...@@ -458,12 +520,12 @@ class SchemaTool ...@@ -458,12 +520,12 @@ class SchemaTool
continue; continue;
} }
$sql[] = $this->_platform->getDropTableSql($class->getTableName()); $orderedTables[] = $class->getTableName();
} }
//TODO: Drop other schema elements, like sequences etc. //TODO: Drop other schema elements, like sequences etc.
return $sql; return $orderedTables;
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment