Skip to content

Instantly share code, notes, and snippets.

@guiguiboy
Last active June 25, 2017 12:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save guiguiboy/8e6d591ce213825847c6f31e07512fa4 to your computer and use it in GitHub Desktop.
Save guiguiboy/8e6d591ce213825847c6f31e07512fa4 to your computer and use it in GitHub Desktop.
Symfony command to quickly compare structure between DB and entities
<?php
namespace AppBundle\Command;
use Doctrine\DBAL\Connection;
use Doctrine\ORM\EntityManager;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class DoctrineDiffCommand extends ContainerAwareCommand
{
/**
* @var EntityManager
*/
protected $em;
/**
* @var Connection
*/
protected $conn;
/**
* @var array
*/
protected $report = array(
'entities' => array(),
'database' => array(),
);
protected function configure()
{
$this
->setName('doctrine:diff')
->setDescription('Compares database with entities')
->setHelp('This command compares the database structure with the entities definition and outputs a report')
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->em = $this->getContainer()->get('doctrine.orm.entity_manager');
$this->conn = $this->getContainer()->get('doctrine.dbal.default_connection');
$this->processEntities();
$this->processDatabase();
$this->processDiff($output, 'database', 'entities');
$this->processDiff($output, 'entities', 'database');
}
protected function processDiff(OutputInterface $output, $from, $to)
{
$output->writeln(sprintf('> Processing diff between %s and %s', $from, $to));
foreach ($this->report[$from] as $expectedTable => $expectedColumns) {
$tableWasFound = false;
foreach ($this->report[$to] as $actualTable => $actualColumns) {
if ($actualTable === $expectedTable) {
$tableWasFound = true;
} else {
continue;
}
foreach ($expectedColumns as $expectedColumn) {
if (!in_array($expectedColumn, $actualColumns)) {
$output->writeln(sprintf('Column %s.%s exists only in %s', $expectedTable, $expectedColumn, $from));
}
}
}
if (!$tableWasFound) {
$output->writeln(sprintf('Table %s exists only in %s', $expectedTable, $from));
}
}
}
protected function processDatabase()
{
$schemaManager = $this->conn->getSchemaManager();
foreach ($schemaManager->listTables() as $table) {
foreach ($schemaManager->listTableColumns($table->getName()) as $column) {
$this->report['database'][$table->getName()][] = $column->getName();
}
}
}
protected function processEntities()
{
$cmf = $this->em->getMetadataFactory();
$classes = $cmf->getAllMetadata();
foreach ($classes as $class) {
$this->report['entities'][$class->getTableName()] = $class->getColumnNames();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment