Skip to content

Commit

Permalink
[DoctrineBundle] Enhancing the Doctrine 2 integration further to bett…
Browse files Browse the repository at this point in the history
…er handle multiple connections/entity managers
  • Loading branch information
jwage authored and fabpot committed Mar 1, 2010
1 parent b3d8aa4 commit 1a45bb6
Show file tree
Hide file tree
Showing 9 changed files with 678 additions and 40 deletions.
139 changes: 139 additions & 0 deletions src/Symfony/Framework/DoctrineBundle/Command/BuildDoctrineCommand.php
@@ -0,0 +1,139 @@
<?php

namespace Symfony\Framework\DoctrineBundle\Command;

use Symfony\Components\Console\Input\InputArgument;
use Symfony\Components\Console\Input\InputOption;
use Symfony\Components\Console\Input\InputInterface;
use Symfony\Components\Console\Output\OutputInterface;
use Symfony\Components\Console\Output\Output;
use Symfony\Framework\WebBundle\Util\Filesystem;
use Doctrine\Common\Cli\Configuration;
use Doctrine\Common\Cli\CliController as DoctrineCliController;
use Doctrine\DBAL\Connection;

/*
* This file is part of the symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

/**
* Build command allows you to easily build and re-build your Doctrine development environment
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
* @author Kris Wallsmith <kris.wallsmith@symfony-project.org>
*/
class BuildDoctrineCommand extends DoctrineCommand
{
const
BUILD_ENTITIES = 1,
BUILD_DB = 16,

OPTION_ENTITIES = 1,
OPTION_DB = 16,
OPTION_ALL = 31;

/**
* @see Command
*/
protected function configure()
{
$this
->setName('doctrine:build')
->setDescription('Build task for easily re-building your Doctrine development environment.')
->addOption('all', null, null, 'Build everything and reset the database')
->addOption('entities', null, null, 'Build model classes')
->addOption('db', null, null, 'Drop database, create database and create schema.')
->addOption('and-load', null, InputOption::PARAMETER_OPTIONAL | InputOption::PARAMETER_IS_ARRAY, 'Load data fixtures')
->addOption('and-append', null, InputOption::PARAMETER_OPTIONAL | InputOption::PARAMETER_IS_ARRAY, 'Load data fixtures and append to existing data')
->addOption('and-update-schema', null, null, 'Update schema after rebuilding all classes')
->addOption('connection', null, null, 'The connection to use.')
;
}

/**
* @see Command
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
if (!$mode = $this->calculateMode($input))
{
throw new \InvalidArgumentException(sprintf("You must include one or more of the following build options:\n--%s\n\nSee this task's help page for more information:\n\n php console help doctrine:build", join(', --', array_keys($this->getBuildOptions()))));
}

if (self::BUILD_ENTITIES == (self::BUILD_ENTITIES & $mode))
{
$this->runCommand('doctrine:build-entities');
}

if (self::BUILD_DB == (self::BUILD_DB & $mode))
{
$this->runCommand('doctrine:schema-tool', array('--re-create' => true, '--connection' => $input->getOption('connection')));
}

if ($input->getOption('and-update-schema'))
{
$this->runCommand('doctrine:schema-tool', array('--update' => true, '--connection' => $input->getOption('connection')));
$this->runCommand('doctrine:schema-tool', array('--complete-update' => true, '--connection' => $input->getOption('connection')));
}

if ($input->hasOption('and-load'))
{
$dirOrFile = $input->getOption('and-load');
$this->runCommand('doctrine:load-data-fixtures',
array('--dir_or_file' => $dirOrFile, '--append' => false)
);
}
else if ($input->hasOption('and-append'))
{
$dirOrFile = $input->getOption('and-append');
$this->runCommand('doctrine:load-data-fixtures', array('--dir_or_file' => $dirOrFile, '--append' => true));
}
}

/**
* Calculates a bit mode based on the supplied options.
*
* @param InputInterface $input
* @return integer
*/
protected function calculateMode(InputInterface $input)
{
$mode = 0;
foreach ($this->getBuildOptions() as $name => $value)
{
if ($input->getOption($name) === true)
{
$mode = $mode | $value;
}
}

return $mode;
}

/**
* Returns an array of valid build options.
*
* @return array An array of option names and their mode
*/
protected function getBuildOptions()
{
$options = array();
foreach ($this->getDefinition()->getOptions() as $option)
{
if (defined($constant = __CLASS__.'::OPTION_'.str_replace('-', '_', strtoupper($option->getName()))))
{
$options[$option->getName()] = constant($constant);
}
}

return $options;
}
}
@@ -0,0 +1,66 @@
<?php

namespace Symfony\Framework\DoctrineBundle\Command;

use Symfony\Components\Console\Input\InputArgument;
use Symfony\Components\Console\Input\InputOption;
use Symfony\Components\Console\Input\InputInterface;
use Symfony\Components\Console\Output\OutputInterface;
use Symfony\Components\Console\Output\Output;
use Symfony\Framework\WebBundle\Util\Filesystem;
use Doctrine\Common\Cli\Configuration;
use Doctrine\Common\Cli\CliController as DoctrineCliController;

/*
* This file is part of the symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

/**
* Build all Bundle entity classes from mapping information.
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
*/
class BuildEntitiesDoctrineCommand extends DoctrineCommand
{
/**
* @see Command
*/
protected function configure()
{
$this
->setName('doctrine:build-entities')
->setDescription('Build all Bundle entity classes from mapping information.')
;
}

/**
* @see Command
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
foreach ($this->container->getParameter('kernel.bundle_dirs') as $bundle => $path)
{
$bundles = glob($path.'/*Bundle');
foreach ($bundles as $p)
{
if (!is_dir($metadataPath = $p.'/Resources/config/doctrine/metadata'))
{
continue;
}
$opts = array();
$opts['--from'] = $metadataPath;
$opts['--to'] = 'annotation';
$opts['--dest'] = realpath($path.'/..');
$this->runCommand('doctrine:convert-mapping', $opts);
}
}
}
}
@@ -0,0 +1,127 @@
<?php

namespace Symfony\Framework\DoctrineBundle\Command;

use Symfony\Components\Console\Input\InputArgument;
use Symfony\Components\Console\Input\InputOption;
use Symfony\Components\Console\Input\InputInterface;
use Symfony\Components\Console\Output\OutputInterface;
use Symfony\Components\Console\Output\Output;
use Symfony\Framework\WebBundle\Util\Filesystem;
use Doctrine\Common\Cli\Configuration;
use Doctrine\Common\Cli\CliController as DoctrineCliController;
use Doctrine\DBAL\Connection;

/*
* This file is part of the symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

/**
* Database tool allows you to easily drop and create your configured databases.
*
* @package symfony
* @subpackage console
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
*/
class DatabaseToolDoctrineCommand extends DoctrineCommand
{
/**
* @see Command
*/
protected function configure()
{
$this
->setName('doctrine:database-tool')
->setDescription('Create and drop the configured databases.')
->addOption('re-create', null, null, 'Drop and re-create your databases.')
->addOption('drop', null, null, 'Drop your databases.')
->addOption('create', null, null, 'Create your databases.')
->addOption('connection', null, null, 'The connection name to work on.')
;
}

/**
* @see Command
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
if ($input->getOption('re-create'))
{
$input->setOption('drop', true);
$input->setOption('create', true);
}
if (!$input->getOption('drop') && !$input->getOption('create'))
{
throw new \InvalidArgumentException('You must specify one of the --drop and --create options or both.');
}
$found = false;
$connections = $this->getDoctrineConnections();
foreach ($connections as $name => $connection)
{
if ($input->getOption('connection') && $name != $input->getOption('connection'))
{
continue;
}
if ($input->getOption('drop'))
{
$this->dropDatabaseForConnection($connection, $output);
}
if ($input->getOption('create'))
{
$this->createDatabaseForConnection($connection, $output);
}
$found = true;
}
if ($found === false)
{
if ($input->getOption('connection'))
{
throw new \InvalidArgumentException(sprintf('<error>Could not find a connection named <comment>%s</comment></error>', $input->getOption('connection')));
}
else
{
throw new \InvalidArgumentException(sprintf('<error>Could not find any configured connections</error>', $input->getOption('connection')));
}
}
}

protected function dropDatabaseForConnection(Connection $connection, OutputInterface $output)
{
$params = $connection->getParams();
$name = isset($params['path']) ? $params['path']:$params['dbname'];

try {
$connection->getSchemaManager()->dropDatabase($name);
$output->writeln(sprintf('<info>Dropped database for connection named <comment>%s</comment></info>', $name));
} catch (\Exception $e) {
$output->writeln(sprintf('<error>Could not drop database for connection named <comment>%s</comment></error>', $name));
$output->writeln(sprintf('<error>%s</error>', $e->getMessage()));
}
}

protected function createDatabaseForConnection(Connection $connection, OutputInterface $output)
{
$params = $connection->getParams();
$name = isset($params['path']) ? $params['path']:$params['dbname'];

unset($params['dbname']);

$tmpConnection = \Doctrine\DBAL\DriverManager::getConnection($params);

try {
$tmpConnection->getSchemaManager()->createDatabase($name);
$output->writeln(sprintf('<info>Created database for connection named <comment>%s</comment></info>', $name));
} catch (\Exception $e) {
$output->writeln(sprintf('<error>Could not create database for connection named <comment>%s</comment></error>', $name));
$output->writeln(sprintf('<error>%s</error>', $e->getMessage()));
}

$tmpConnection->close();
}
}

0 comments on commit 1a45bb6

Please sign in to comment.