Skip to content

Commit

Permalink
Whilelist existing assets we know about from metadata in SchemaTool::…
Browse files Browse the repository at this point in the history
…getUpdateSchemaSql()
  • Loading branch information
nicolas-grekas committed Oct 21, 2019
1 parent 9fef4e8 commit 86c4ba2
Showing 1 changed file with 43 additions and 2 deletions.
45 changes: 43 additions & 2 deletions lib/Doctrine/ORM/Tools/SchemaTool.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@

namespace Doctrine\ORM\Tools;

use Doctrine\ORM\ORMException;
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\Schema\AbstractAsset;
use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Schema;
Expand All @@ -28,8 +29,10 @@
use Doctrine\DBAL\Schema\Visitor\RemoveNamespacedAssets;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\ORMException;
use Doctrine\ORM\Tools\Event\GenerateSchemaTableEventArgs;
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
use function method_exists;

/**
* The SchemaTool is a tool to create/drop/update database schemas based on
Expand Down Expand Up @@ -898,9 +901,47 @@ public function getUpdateSchemaSql(array $classes, $saveMode = false)
{
$sm = $this->em->getConnection()->getSchemaManager();

$fromSchema = $sm->createSchema();
$toSchema = $this->getSchemaFromMetadata($classes);

// check and memorize if we are using dbal >= 2.9
static $hasFilterMethod;
$hasFilterMethod = $hasFilterMethod ?? method_exists(Configuration::class, 'getSchemaAssetsFilter');
$config = $this->em->getConnection()->getConfiguration();
$filter = null;
$filterExpression = null;

if ($hasFilterMethod) {
// check and memorize if we are using dbal >= 3.0
static $hasFilterExpressionMethod;
$hasFilterExpressionMethod = $hasFilterExpressionMethod ?? method_exists(Configuration::class, 'getFilterSchemaAssetsExpression');

// backup schema assets filter and filter-expression
$filterExpression = $hasFilterExpressionMethod ? $config->getFilterSchemaAssetsExpression() : null;
$filter = $config->getSchemaAssetsFilter();

if ($filter !== null) {
// whitelist assets we already know about in $toSchema, use the existing filter otherwise
$config->setSchemaAssetsFilter(static function ($asset) use ($filter, $toSchema) : bool {
$assetName = $asset instanceof AbstractAsset ? $asset->getName() : $asset;

return $toSchema->hasTable($assetName) || $toSchema->hasSequence($assetName) || $filter($asset);
});
}
}

try {
$fromSchema = $sm->createSchema();
} finally {
if ($hasFilterMethod && $filter !== null) {
// restore schema assets filter and filter-expression
if ($filterExpression !== null) {
$config->setFilterSchemaAssetsExpression($filterExpression);
} else {
$config->setSchemaAssetsFilter($filter);
}
}
}

$comparator = new Comparator();
$schemaDiff = $comparator->compare($fromSchema, $toSchema);

Expand Down

0 comments on commit 86c4ba2

Please sign in to comment.