1
0
mirror of synced 2024-12-13 14:56:01 +03:00

Merge remote-tracking branch 'origin/master' into codegenerationfixes

This commit is contained in:
Nick Masters 2012-11-04 15:14:54 +00:00
commit 3a8ea7260c
46 changed files with 687 additions and 534 deletions

View File

@ -576,11 +576,22 @@ class Configuration extends \Doctrine\DBAL\Configuration
* Add a filter to the list of possible filters.
*
* @param string $name The name of the filter.
* @param string $className The class name of the filter.
* @param string|Query\Filter\SQLFilter $filter The filter class name or an
* SQLFilter instance.
*
* @throws \InvalidArgumentException If the filter is an object and it doesn't
* extend the Query\Filter\SQLFilter class.
*/
public function addFilter($name, $className)
public function addFilter($name, $filter)
{
$this->_attributes['filters'][$name] = $className;
if (is_object($filter) && ! $filter instanceof Query\Filter\SQLFilter) {
throw new \InvalidArgumentException(
"A filter can be either a class name or an object extending \Doctrine\ORM\Query\Filter\SQLFilter," .
" instance of '" . get_class($filter) . "' given."
);
}
$this->_attributes['filters'][$name] = $filter;
}
/**
@ -588,10 +599,10 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @param string $name The name of the filter.
*
* @return string The class name of the filter, or null of it is not
* defined.
* @return string|Query\Filter\SQLFilter The class name of the filter, an
* SQLFilter instance or null of it is not defined.
*/
public function getFilterClassName($name)
public function getFilter($name)
{
return isset($this->_attributes['filters'][$name])
? $this->_attributes['filters'][$name]

View File

@ -1680,7 +1680,7 @@ class BasicEntityPersister
}
/**
* Retrieve an invidiual parameter value
* Retrieve an individual parameter value
*
* @param mixed $value
* @return mixed

View File

@ -103,12 +103,14 @@ class FilterCollection
*/
public function enable($name)
{
if (null === $filterClass = $this->config->getFilterClassName($name)) {
if (null === $filter = $this->config->getFilter($name)) {
throw new \InvalidArgumentException("Filter '" . $name . "' does not exist.");
}
if (!isset($this->enabledFilters[$name])) {
$this->enabledFilters[$name] = new $filterClass($this->em);
$this->enabledFilters[$name] = is_object($filter)
? $filter
: new $filter($this->em);
// Keep the enabled filters sorted for the hash
ksort($this->enabledFilters);

View File

@ -507,13 +507,12 @@ class Parser
*/
private function isFunction()
{
$peek = $this->lexer->peek();
$nextpeek = $this->lexer->peek();
$lookaheadType = $this->lexer->lookahead['type'];
$peek = $this->lexer->peek();
$this->lexer->resetPeek();
// We deny the COUNT(SELECT * FROM User u) here. COUNT won't be considered a function
return ($peek['type'] === Lexer::T_OPEN_PARENTHESIS && $nextpeek['type'] !== Lexer::T_SELECT);
return ($lookaheadType >= Lexer::T_IDENTIFIER && $peek['type'] === Lexer::T_OPEN_PARENTHESIS);
}
/**
@ -1786,9 +1785,55 @@ class Parser
public function ScalarExpression()
{
$lookahead = $this->lexer->lookahead['type'];
$peek = $this->lexer->glimpse();
switch ($lookahead) {
case Lexer::T_IDENTIFIER:
switch (true) {
case ($lookahead === Lexer::T_INTEGER):
case ($lookahead === Lexer::T_FLOAT):
return $this->SimpleArithmeticExpression();
case ($lookahead === Lexer::T_STRING):
return $this->StringPrimary();
case ($lookahead === Lexer::T_TRUE):
case ($lookahead === Lexer::T_FALSE):
$this->match($lookahead);
return new AST\Literal(AST\Literal::BOOLEAN, $this->lexer->token['value']);
case ($lookahead === Lexer::T_INPUT_PARAMETER):
return $this->InputParameter();
case ($lookahead === Lexer::T_CASE):
case ($lookahead === Lexer::T_COALESCE):
case ($lookahead === Lexer::T_NULLIF):
// Since NULLIF and COALESCE can be identified as a function,
// we need to check these before checking for FunctionDeclaration
return $this->CaseExpression();
case ($lookahead === Lexer::T_OPEN_PARENTHESIS):
return $this->SimpleArithmeticExpression();
//this check must be done before checking for a filed path expression
case ($this->isFunction()):
$this->lexer->peek(); // "("
switch (true) {
case ($this->isMathOperator($this->peekBeyondClosingParenthesis())):
// SUM(u.id) + COUNT(u.id)
return $this->SimpleArithmeticExpression();
case ($this->isAggregateFunction($this->lexer->lookahead['type'])):
return $this->AggregateExpression();
default:
// IDENTITY(u)
return $this->FunctionDeclaration();
}
break;
//it is no function, so it must be a field path
case ($lookahead === Lexer::T_IDENTIFIER):
$this->lexer->peek(); // lookahead => '.'
$this->lexer->peek(); // lookahead => token after '.'
$peek = $this->lexer->peek(); // lookahead => token after the token after the '.'
@ -1800,47 +1845,8 @@ class Parser
return $this->StateFieldPathExpression();
case Lexer::T_INTEGER:
case Lexer::T_FLOAT:
return $this->SimpleArithmeticExpression();
case Lexer::T_STRING:
return $this->StringPrimary();
case Lexer::T_TRUE:
case Lexer::T_FALSE:
$this->match($lookahead);
return new AST\Literal(AST\Literal::BOOLEAN, $this->lexer->token['value']);
case Lexer::T_INPUT_PARAMETER:
return $this->InputParameter();
case Lexer::T_CASE:
case Lexer::T_COALESCE:
case Lexer::T_NULLIF:
// Since NULLIF and COALESCE can be identified as a function,
// we need to check if before check for FunctionDeclaration
return $this->CaseExpression();
default:
if ( ! ($this->isFunction() || $this->isAggregateFunction($lookahead))) {
$this->syntaxError();
}
// We may be in an ArithmeticExpression (find the matching ")" and inspect for Math operator)
$this->lexer->peek(); // "("
$peek = $this->peekBeyondClosingParenthesis();
if ($this->isMathOperator($peek)) {
return $this->SimpleArithmeticExpression();
}
if ($this->isAggregateFunction($this->lexer->lookahead['type'])) {
return $this->AggregateExpression();
}
return $this->FunctionDeclaration();
$this->syntaxError();
}
}

View File

@ -1700,7 +1700,7 @@ class SqlWalker implements TreeWalker
if (count($filterClauses)) {
if ($condSql) {
$condSql .= ' AND ';
$condSql = '(' . $condSql . ') AND ';
}
$condSql .= implode(' AND ', $filterClauses);

View File

@ -19,10 +19,11 @@
namespace Doctrine\ORM\Tools\Console\Command\ClearCache;
use Symfony\Component\Console\Input\InputArgument,
Symfony\Component\Console\Input\InputOption,
Symfony\Component\Console,
Doctrine\Common\Cache;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\Common\Cache\ApcCache;
/**
* Command to clear the metadata cache of the various cache drivers.
@ -35,7 +36,7 @@ use Symfony\Component\Console\Input\InputArgument,
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class MetadataCommand extends Console\Command\Command
class MetadataCommand extends Command
{
/**
* @see Console\Command\Command
@ -75,7 +76,7 @@ EOT
/**
* @see Console\Command\Command
*/
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->getHelper('em')->getEntityManager();
$cacheDriver = $em->getConfiguration()->getMetadataCacheImpl();
@ -84,11 +85,11 @@ EOT
throw new \InvalidArgumentException('No Metadata cache driver is configured on given EntityManager.');
}
if ($cacheDriver instanceof Cache\ApcCache) {
if ($cacheDriver instanceof ApcCache) {
throw new \LogicException("Cannot clear APC Cache from Console, its shared in the Webserver memory and not accessible from the CLI.");
}
$output->write('Clearing ALL Metadata cache entries' . PHP_EOL);
$output->writeln('Clearing ALL Metadata cache entries');
$result = $cacheDriver->deleteAll();
$message = ($result) ? 'Successfully deleted cache entries.' : 'No cache entries were deleted.';
@ -98,6 +99,6 @@ EOT
$message = ($result) ? 'Successfully flushed cache entries.' : $message;
}
$output->write($message . PHP_EOL);
$output->writeln($message);
}
}

View File

@ -19,10 +19,11 @@
namespace Doctrine\ORM\Tools\Console\Command\ClearCache;
use Symfony\Component\Console\Input\InputArgument,
Symfony\Component\Console\Input\InputOption,
Symfony\Component\Console,
Doctrine\Common\Cache;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\Common\Cache\ApcCache;
/**
* Command to clear the query cache of the various cache drivers.
@ -35,11 +36,8 @@ use Symfony\Component\Console\Input\InputArgument,
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class QueryCommand extends Console\Command\Command
class QueryCommand extends Command
{
/**
* @see Console\Command\Command
*/
protected function configure()
{
$this
@ -72,10 +70,7 @@ EOT
);
}
/**
* @see Console\Command\Command
*/
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->getHelper('em')->getEntityManager();
$cacheDriver = $em->getConfiguration()->getQueryCacheImpl();
@ -84,7 +79,7 @@ EOT
throw new \InvalidArgumentException('No Query cache driver is configured on given EntityManager.');
}
if ($cacheDriver instanceof Cache\ApcCache) {
if ($cacheDriver instanceof ApcCache) {
throw new \LogicException("Cannot clear APC Cache from Console, its shared in the Webserver memory and not accessible from the CLI.");
}

View File

@ -19,10 +19,11 @@
namespace Doctrine\ORM\Tools\Console\Command\ClearCache;
use Symfony\Component\Console\Input\InputArgument,
Symfony\Component\Console\Input\InputOption,
Symfony\Component\Console,
Doctrine\Common\Cache;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\Common\Cache\ApcCache;
/**
* Command to clear the result cache of the various cache drivers.
@ -35,7 +36,7 @@ use Symfony\Component\Console\Input\InputArgument,
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class ResultCommand extends Console\Command\Command
class ResultCommand extends Command
{
/**
* @see Console\Command\Command
@ -75,7 +76,7 @@ EOT
/**
* @see Console\Command\Command
*/
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->getHelper('em')->getEntityManager();
$cacheDriver = $em->getConfiguration()->getResultCacheImpl();
@ -84,11 +85,11 @@ EOT
throw new \InvalidArgumentException('No Result cache driver is configured on given EntityManager.');
}
if ($cacheDriver instanceof Cache\ApcCache) {
if ($cacheDriver instanceof ApcCache) {
throw new \LogicException("Cannot clear APC Cache from Console, its shared in the Webserver memory and not accessible from the CLI.");
}
$output->write('Clearing ALL Result cache entries' . PHP_EOL);
$output->writeln('Clearing ALL Result cache entries');
$result = $cacheDriver->deleteAll();
$message = ($result) ? 'Successfully deleted cache entries.' : 'No cache entries were deleted.';
@ -98,6 +99,6 @@ EOT
$message = ($result) ? 'Successfully flushed cache entries.' : $message;
}
$output->write($message . PHP_EOL);
$output->writeln($message);
}
}

View File

@ -25,11 +25,15 @@ use Symfony\Component\Console\Input\InputArgument,
Doctrine\ORM\Tools\Export\ClassMetadataExporter,
Doctrine\ORM\Tools\ConvertDoctrine1Schema,
Doctrine\ORM\Tools\EntityGenerator;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Command\Command;
/**
* Command to convert a Doctrine 1 schema to a Doctrine 2 mapping file.
*
*
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
@ -37,7 +41,7 @@ use Symfony\Component\Console\Input\InputArgument,
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class ConvertDoctrine1SchemaCommand extends Console\Command\Command
class ConvertDoctrine1SchemaCommand extends Command
{
/**
* @var EntityGenerator
@ -128,13 +132,8 @@ EOT
);
}
/**
* @see Console\Command\Command
*/
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->getHelper('em')->getEntityManager();
// Process source directories
$fromPaths = array_merge(array($input->getArgument('from-path')), $input->getOption('from'));
@ -145,19 +144,18 @@ EOT
$extend = $input->getOption('extend');
$numSpaces = $input->getOption('num-spaces');
$this->convertDoctrine1Schema($em, $fromPaths, $destPath, $toType, $numSpaces, $extend, $output);
$this->convertDoctrine1Schema($fromPaths, $destPath, $toType, $numSpaces, $extend, $output);
}
/**
* @param \Doctrine\ORM\EntityManager $em
* @param array $fromPaths
* @param string $destPath
* @param string $toType
* @param int $numSpaces
* @param string|null $extend
* @param Console\Output\OutputInterface $output
* @param OutputInterface $output
*/
public function convertDoctrine1Schema($em, $fromPaths, $destPath, $toType, $numSpaces, $extend, $output)
public function convertDoctrine1Schema(array $fromPaths, $destPath, $toType, $numSpaces, $extend, OutputInterface $output)
{
foreach ($fromPaths as &$dirName) {
$dirName = realpath($dirName);
@ -166,7 +164,9 @@ EOT
throw new \InvalidArgumentException(
sprintf("Doctrine 1.X schema directory '<info>%s</info>' does not exist.", $dirName)
);
} else if ( ! is_readable($dirName)) {
}
if ( ! is_readable($dirName)) {
throw new \InvalidArgumentException(
sprintf("Doctrine 1.X schema directory '<info>%s</info>' does not have read permissions.", $dirName)
);
@ -177,7 +177,9 @@ EOT
throw new \InvalidArgumentException(
sprintf("Doctrine 2.X mapping destination directory '<info>%s</info>' does not exist.", $destPath)
);
} else if ( ! is_writable($destPath)) {
}
if ( ! is_writable($destPath)) {
throw new \InvalidArgumentException(
sprintf("Doctrine 2.X mapping destination directory '<info>%s</info>' does not have write permissions.", $destPath)
);
@ -201,20 +203,20 @@ EOT
$metadata = $converter->getMetadata();
if ($metadata) {
$output->write(PHP_EOL);
$output->writeln('');
foreach ($metadata as $class) {
$output->write(sprintf('Processing entity "<info>%s</info>"', $class->name) . PHP_EOL);
$output->writeln(sprintf('Processing entity "<info>%s</info>"', $class->name));
}
$exporter->setMetadata($metadata);
$exporter->export();
$output->write(PHP_EOL . sprintf(
$output->writeln(PHP_EOL . sprintf(
'Converting Doctrine 1.X schema to "<info>%s</info>" mapping type in "<info>%s</info>"', $toType, $destPath
));
} else {
$output->write('No Metadata Classes to process.' . PHP_EOL);
$output->writeln('No Metadata Classes to process.');
}
}
}

View File

@ -21,16 +21,19 @@ namespace Doctrine\ORM\Tools\Console\Command;
use Symfony\Component\Console\Input\InputArgument,
Symfony\Component\Console\Input\InputOption,
Symfony\Component\Console,
Doctrine\ORM\Tools\Console\MetadataFilter,
Doctrine\ORM\Tools\Export\ClassMetadataExporter,
Doctrine\ORM\Tools\EntityGenerator,
Doctrine\ORM\Tools\DisconnectedClassMetadataFactory;
use Doctrine\ORM\Mapping\Driver\DatabaseDriver;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Command\Command;
/**
* Command to convert your mapping information between the various formats.
*
*
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
@ -38,11 +41,8 @@ use Symfony\Component\Console\Input\InputArgument,
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class ConvertMappingCommand extends Console\Command\Command
class ConvertMappingCommand extends Command
{
/**
* @see Console\Command\Command
*/
protected function configure()
{
$this
@ -100,15 +100,12 @@ EOT
);
}
/**
* @see Console\Command\Command
*/
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->getHelper('em')->getEntityManager();
if ($input->getOption('from-database') === true) {
$databaseDriver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver(
$databaseDriver = new DatabaseDriver(
$em->getConnection()->getSchemaManager()
);
@ -136,7 +133,9 @@ EOT
throw new \InvalidArgumentException(
sprintf("Mapping destination directory '<info>%s</info>' does not exist.", $input->getArgument('dest-path'))
);
} else if ( ! is_writable($destPath)) {
}
if ( ! is_writable($destPath)) {
throw new \InvalidArgumentException(
sprintf("Mapping destination directory '<info>%s</info>' does not have write permissions.", $destPath)
);
@ -145,7 +144,7 @@ EOT
$toType = strtolower($input->getArgument('to-type'));
$exporter = $this->getExporter($toType, $destPath);
$exporter->setOverwriteExistingFiles( ($input->getOption('force') !== false) );
$exporter->setOverwriteExistingFiles($input->getOption('force'));
if ($toType == 'annotation') {
$entityGenerator = new EntityGenerator();
@ -160,20 +159,26 @@ EOT
if (count($metadata)) {
foreach ($metadata as $class) {
$output->write(sprintf('Processing entity "<info>%s</info>"', $class->name) . PHP_EOL);
$output->writeln(sprintf('Processing entity "<info>%s</info>"', $class->name));
}
$exporter->setMetadata($metadata);
$exporter->export();
$output->write(PHP_EOL . sprintf(
'Exporting "<info>%s</info>" mapping information to "<info>%s</info>"' . PHP_EOL, $toType, $destPath
$output->writeln(PHP_EOL . sprintf(
'Exporting "<info>%s</info>" mapping information to "<info>%s</info>"', $toType, $destPath
));
} else {
$output->write('No Metadata Classes to process.' . PHP_EOL);
$output->writeln('No Metadata Classes to process.');
}
}
/**
* @param $toType
* @param $destPath
*
* @return \Doctrine\ORM\Tools\Export\Driver\AbstractExporter
*/
protected function getExporter($toType, $destPath)
{
$cme = new ClassMetadataExporter();

View File

@ -19,14 +19,15 @@
namespace Doctrine\ORM\Tools\Console\Command;
use Symfony\Component\Console\Input\InputArgument,
Symfony\Component\Console\Input\InputOption,
Symfony\Component\Console;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Command to ensure that Doctrine is properly configured for a production environment.
*
*
*
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
@ -35,11 +36,8 @@ use Symfony\Component\Console\Input\InputArgument,
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class EnsureProductionSettingsCommand extends Console\Command\Command
class EnsureProductionSettingsCommand extends Command
{
/**
* @see Console\Command\Command
*/
protected function configure()
{
$this
@ -57,14 +55,10 @@ EOT
);
}
/**
* @see Console\Command\Command
*/
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->getHelper('em')->getEntityManager();
$error = false;
try {
$em->getConfiguration()->ensureProductionSettings();
@ -72,12 +66,11 @@ EOT
$em->getConnection()->connect();
}
} catch (\Exception $e) {
$error = true;
$output->writeln('<error>' . $e->getMessage() . '</error>');
return 1;
}
if ($error === false) {
$output->write('<info>Environment is correctly configured for production.</info>' . PHP_EOL);
}
$output->writeln('<info>Environment is correctly configured for production.</info>');
}
}

View File

@ -21,15 +21,17 @@ namespace Doctrine\ORM\Tools\Console\Command;
use Symfony\Component\Console\Input\InputArgument,
Symfony\Component\Console\Input\InputOption,
Symfony\Component\Console,
Doctrine\ORM\Tools\Console\MetadataFilter,
Doctrine\ORM\Tools\EntityGenerator,
Doctrine\ORM\Tools\DisconnectedClassMetadataFactory;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Command\Command;
/**
* Command to generate entity classes and method stubs from your mapping information.
*
*
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
@ -37,7 +39,7 @@ use Symfony\Component\Console\Input\InputArgument,
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class GenerateEntitiesCommand extends Console\Command\Command
class GenerateEntitiesCommand extends Command
{
/**
* @see Console\Command\Command
@ -106,7 +108,7 @@ EOT
/**
* @see Console\Command\Command
*/
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->getHelper('em')->getEntityManager();
@ -122,7 +124,9 @@ EOT
throw new \InvalidArgumentException(
sprintf("Entities destination directory '<info>%s</info>' does not exist.", $input->getArgument('dest-path'))
);
} else if ( ! is_writable($destPath)) {
}
if ( ! is_writable($destPath)) {
throw new \InvalidArgumentException(
sprintf("Entities destination directory '<info>%s</info>' does not have write permissions.", $destPath)
);
@ -143,8 +147,8 @@ EOT
}
foreach ($metadatas as $metadata) {
$output->write(
sprintf('Processing entity "<info>%s</info>"', $metadata->name) . PHP_EOL
$output->writeln(
sprintf('Processing entity "<info>%s</info>"', $metadata->name)
);
}
@ -152,9 +156,9 @@ EOT
$entityGenerator->generate($metadatas, $destPath);
// Outputting information message
$output->write(PHP_EOL . sprintf('Entity classes generated to "<info>%s</INFO>"', $destPath) . PHP_EOL);
$output->writeln(PHP_EOL . sprintf('Entity classes generated to "<info>%s</INFO>"', $destPath));
} else {
$output->write('No Metadata Classes to process.' . PHP_EOL);
$output->writeln('No Metadata Classes to process.');
}
}
}

View File

@ -21,13 +21,15 @@ namespace Doctrine\ORM\Tools\Console\Command;
use Symfony\Component\Console\Input\InputArgument,
Symfony\Component\Console\Input\InputOption,
Symfony\Component\Console,
Doctrine\ORM\Tools\Console\MetadataFilter;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Command\Command;
/**
* Command to (re)generate the proxy classes used by doctrine.
*
*
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
@ -35,11 +37,8 @@ use Symfony\Component\Console\Input\InputArgument,
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class GenerateProxiesCommand extends Console\Command\Command
class GenerateProxiesCommand extends Command
{
/**
* @see Console\Command\Command
*/
protected function configure()
{
$this
@ -61,10 +60,7 @@ EOT
);
}
/**
* @see Console\Command\Command
*/
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->getHelper('em')->getEntityManager();
@ -86,7 +82,9 @@ EOT
throw new \InvalidArgumentException(
sprintf("Proxies destination directory '<info>%s</info>' does not exist.", $em->getConfiguration()->getProxyDir())
);
} else if ( ! is_writable($destPath)) {
}
if ( ! is_writable($destPath)) {
throw new \InvalidArgumentException(
sprintf("Proxies destination directory '<info>%s</info>' does not have write permissions.", $destPath)
);
@ -94,8 +92,8 @@ EOT
if ( count($metadatas)) {
foreach ($metadatas as $metadata) {
$output->write(
sprintf('Processing entity "<info>%s</info>"', $metadata->name) . PHP_EOL
$output->writeln(
sprintf('Processing entity "<info>%s</info>"', $metadata->name)
);
}
@ -103,9 +101,9 @@ EOT
$em->getProxyFactory()->generateProxyClasses($metadatas, $destPath);
// Outputting information message
$output->write(PHP_EOL . sprintf('Proxy classes generated to "<info>%s</INFO>"', $destPath) . PHP_EOL);
$output->writeln(PHP_EOL . sprintf('Proxy classes generated to "<info>%s</INFO>"', $destPath));
} else {
$output->write('No Metadata Classes to process.' . PHP_EOL);
$output->writeln('No Metadata Classes to process.');
}
}

View File

@ -21,14 +21,16 @@ namespace Doctrine\ORM\Tools\Console\Command;
use Symfony\Component\Console\Input\InputArgument,
Symfony\Component\Console\Input\InputOption,
Symfony\Component\Console,
Doctrine\ORM\Tools\Console\MetadataFilter,
Doctrine\ORM\Tools\EntityRepositoryGenerator;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Command\Command;
/**
* Command to generate repository classes for mapping information.
*
*
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
@ -36,11 +38,8 @@ use Symfony\Component\Console\Input\InputArgument,
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class GenerateRepositoriesCommand extends Console\Command\Command
class GenerateRepositoriesCommand extends Command
{
/**
* @see Console\Command\Command
*/
protected function configure()
{
$this
@ -61,10 +60,7 @@ EOT
);
}
/**
* @see Console\Command\Command
*/
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->getHelper('em')->getEntityManager();
@ -78,7 +74,9 @@ EOT
throw new \InvalidArgumentException(
sprintf("Entities destination directory '<info>%s</info>' does not exist.", $input->getArgument('dest-path'))
);
} else if ( ! is_writable($destPath)) {
}
if ( ! is_writable($destPath)) {
throw new \InvalidArgumentException(
sprintf("Entities destination directory '<info>%s</info>' does not have write permissions.", $destPath)
);
@ -90,8 +88,8 @@ EOT
foreach ($metadatas as $metadata) {
if ($metadata->customRepositoryClassName) {
$output->write(
sprintf('Processing repository "<info>%s</info>"', $metadata->customRepositoryClassName) . PHP_EOL
$output->writeln(
sprintf('Processing repository "<info>%s</info>"', $metadata->customRepositoryClassName)
);
$generator->writeEntityRepositoryClass($metadata->customRepositoryClassName, $destPath);
@ -102,12 +100,12 @@ EOT
if ($numRepositories) {
// Outputting information message
$output->write(PHP_EOL . sprintf('Repository classes generated to "<info>%s</INFO>"', $destPath) . PHP_EOL);
$output->writeln(PHP_EOL . sprintf('Repository classes generated to "<info>%s</INFO>"', $destPath) );
} else {
$output->write('No Repository classes were found to be processed.' . PHP_EOL);
$output->writeln('No Repository classes were found to be processed.' );
}
} else {
$output->write('No Metadata Classes to process.' . PHP_EOL);
$output->writeln('No Metadata Classes to process.' );
}
}
}

View File

@ -65,6 +65,8 @@ EOT
$output->writeln(sprintf("Found <info>%d</info> mapped entities:", count($entityClassNames)));
$failure = false;
foreach ($entityClassNames as $entityClassName) {
try {
$entityManager->getClassMetadata($entityClassName);
@ -73,7 +75,11 @@ EOT
$output->writeln("<error>[FAIL]</error> ".$entityClassName);
$output->writeln(sprintf("<comment>%s</comment>", $e->getMessage()));
$output->writeln('');
$failure = true;
}
}
return $failure ? 1 : 0;
}
}

View File

@ -19,14 +19,17 @@
namespace Doctrine\ORM\Tools\Console\Command;
use Symfony\Component\Console\Input\InputArgument,
Symfony\Component\Console\Input\InputOption,
Symfony\Component\Console;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\Common\Util\Debug;
/**
* Command to execute DQL queries in a given EntityManager.
*
*
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
@ -34,11 +37,8 @@ use Symfony\Component\Console\Input\InputArgument,
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class RunDqlCommand extends Console\Command\Command
class RunDqlCommand extends Command
{
/**
* @see Console\Command\Command
*/
protected function configure()
{
$this
@ -70,10 +70,7 @@ EOT
);
}
/**
* @see Console\Command\Command
*/
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->getHelper('em')->getEntityManager();
@ -116,6 +113,6 @@ EOT
$resultSet = $query->execute(array(), constant($hydrationMode));
\Doctrine\Common\Util\Debug::dump($resultSet, $input->getOption('depth'));
Debug::dump($resultSet, $input->getOption('depth'));
}
}

View File

@ -27,10 +27,10 @@ use Symfony\Component\Console\Input\InputInterface,
abstract class AbstractCommand extends Command
{
/**
* @param InputInterface $input
* @param InputInterface $input
* @param OutputInterface $output
* @param SchemaTool $schemaTool
* @param array $metadatas
* @param SchemaTool $schemaTool
* @param array $metadatas
*/
abstract protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas);
@ -48,11 +48,11 @@ abstract class AbstractCommand extends Command
if ( ! empty($metadatas)) {
// Create SchemaTool
$tool = new \Doctrine\ORM\Tools\SchemaTool($em);
$tool = new SchemaTool($em);
$this->executeSchemaCommand($input, $output, $tool, $metadatas);
return $this->executeSchemaCommand($input, $output, $tool, $metadatas);
} else {
$output->write('No Metadata Classes to process.' . PHP_EOL);
$output->writeln('No Metadata Classes to process.');
}
}
}

View File

@ -28,7 +28,7 @@ use Symfony\Component\Console\Input\InputArgument,
/**
* Command to create the database schema for a set of classes based on their mappings.
*
*
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
@ -62,15 +62,15 @@ EOT
protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas)
{
if ($input->getOption('dump-sql') === true) {
if ($input->getOption('dump-sql')) {
$sqls = $schemaTool->getCreateSchemaSql($metadatas);
$output->write(implode(';' . PHP_EOL, $sqls) . ';' . PHP_EOL);
$output->writeln(implode(';' . PHP_EOL, $sqls) . ';');
} else {
$output->write('ATTENTION: This operation should not be executed in a production environment.' . PHP_EOL . PHP_EOL);
$output->writeln('ATTENTION: This operation should not be executed in a production environment.' . PHP_EOL);
$output->write('Creating database schema...' . PHP_EOL);
$output->writeln('Creating database schema...');
$schemaTool->createSchema($metadatas);
$output->write('Database schema created successfully!' . PHP_EOL);
$output->writeln('Database schema created successfully!');
}
}
}

View File

@ -28,7 +28,7 @@ use Symfony\Component\Console\Input\InputArgument,
/**
* Command to drop the database schema for a set of classes based on their mappings.
*
*
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
@ -71,38 +71,48 @@ EOT
protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas)
{
$isFullDatabaseDrop = ($input->getOption('full-database'));
$isFullDatabaseDrop = $input->getOption('full-database');
if ($input->getOption('dump-sql') === true) {
if ($input->getOption('dump-sql')) {
if ($isFullDatabaseDrop) {
$sqls = $schemaTool->getDropDatabaseSQL();
} else {
$sqls = $schemaTool->getDropSchemaSQL($metadatas);
}
$output->write(implode(';' . PHP_EOL, $sqls) . PHP_EOL);
} else if ($input->getOption('force') === true) {
$output->write('Dropping database schema...' . PHP_EOL);
$output->writeln(implode(';' . PHP_EOL, $sqls));
return 0;
}
if ($input->getOption('force')) {
$output->writeln('Dropping database schema...');
if ($isFullDatabaseDrop) {
$schemaTool->dropDatabase();
} else {
$schemaTool->dropSchema($metadatas);
}
$output->write('Database schema dropped successfully!' . PHP_EOL);
} else {
$output->write('ATTENTION: This operation should not be executed in a production environment.' . PHP_EOL . PHP_EOL);
if ($isFullDatabaseDrop) {
$sqls = $schemaTool->getDropDatabaseSQL();
} else {
$sqls = $schemaTool->getDropSchemaSQL($metadatas);
}
$output->writeln('Database schema dropped successfully!');
if (count($sqls)) {
$output->write('Schema-Tool would execute ' . count($sqls) . ' queries to drop the database.' . PHP_EOL);
$output->write('Please run the operation with --force to execute these queries or use --dump-sql to see them.' . PHP_EOL);
} else {
$output->write('Nothing to drop. The database is empty!' . PHP_EOL);
}
return 0;
}
$output->writeln('ATTENTION: This operation should not be executed in a production environment.' . PHP_EOL);
if ($isFullDatabaseDrop) {
$sqls = $schemaTool->getDropDatabaseSQL();
} else {
$sqls = $schemaTool->getDropSchemaSQL($metadatas);
}
if (count($sqls)) {
$output->writeln('Schema-Tool would execute ' . count($sqls) . ' queries to drop the database.');
$output->writeln('Please run the operation with --force to execute these queries or use --dump-sql to see them.');
return 1;
}
$output->writeln('Nothing to drop. The database is empty!');
}
}

View File

@ -94,38 +94,48 @@ EOT
protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas)
{
// Defining if update is complete or not (--complete not defined means $saveMode = true)
$saveMode = ($input->getOption('complete') !== true);
$saveMode = ! $input->getOption('complete');
$sqls = $schemaTool->getUpdateSchemaSql($metadatas, $saveMode);
if (0 == count($sqls)) {
if (0 === count($sqls)) {
$output->writeln('Nothing to update - your database is already in sync with the current entity metadata.');
return;
}
$dumpSql = (true === $input->getOption('dump-sql'));
$force = (true === $input->getOption('force'));
$dumpSql = true === $input->getOption('dump-sql');
$force = true === $input->getOption('force');
if ($dumpSql && $force) {
throw new \InvalidArgumentException('You can pass either the --dump-sql or the --force option (but not both simultaneously).');
}
if ($dumpSql) {
$output->writeln(implode(';' . PHP_EOL, $sqls));
} else if ($force) {
return 0;
}
if ($force) {
$output->writeln('Updating database schema...');
$schemaTool->updateSchema($metadatas, $saveMode);
$output->writeln(sprintf('Database schema updated successfully! "<info>%s</info>" queries were executed', count($sqls)));
} else {
$output->writeln('<comment>ATTENTION</comment>: This operation should not be executed in a production environment.');
$output->writeln(' Use the incremental update to detect changes during development and use');
$output->writeln(' the SQL DDL provided to manually update your database in production.');
$output->writeln('');
$output->writeln(sprintf('The Schema-Tool would execute <info>"%s"</info> queries to update the database.', count($sqls)));
$output->writeln('Please run the operation by passing one of the following options:');
$output->writeln(sprintf(' <info>%s --force</info> to execute the command', $this->getName()));
$output->writeln(sprintf(' <info>%s --dump-sql</info> to dump the SQL statements to the screen', $this->getName()));
return 0;
}
$output->writeln('<comment>ATTENTION</comment>: This operation should not be executed in a production environment.');
$output->writeln(' Use the incremental update to detect changes during development and use');
$output->writeln(' the SQL DDL provided to manually update your database in production.');
$output->writeln('');
$output->writeln(sprintf('The Schema-Tool would execute <info>"%s"</info> queries to update the database.', count($sqls)));
$output->writeln('Please run the operation by passing one of the following options:');
$output->writeln(sprintf(' <info>%s --force</info> to execute the command', $this->getName()));
$output->writeln(sprintf(' <info>%s --dump-sql</info> to dump the SQL statements to the screen', $this->getName()));
return 1;
}
}

View File

@ -19,9 +19,10 @@
namespace Doctrine\ORM\Tools\Console\Command;
use Symfony\Component\Console\Input\InputArgument,
Symfony\Component\Console\Input\InputOption,
Symfony\Component\Console;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\Tools\SchemaValidator;
/**
* Validate that the current mapping is valid
@ -34,11 +35,8 @@ use Symfony\Component\Console\Input\InputArgument,
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class ValidateSchemaCommand extends Console\Command\Command
class ValidateSchemaCommand extends Command
{
/**
* @see Console\Command\Command
*/
protected function configure()
{
$this
@ -50,35 +48,35 @@ EOT
);
}
/**
* @see Console\Command\Command
*/
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->getHelper('em')->getEntityManager();
$validator = new \Doctrine\ORM\Tools\SchemaValidator($em);
$validator = new SchemaValidator($em);
$errors = $validator->validateMapping();
$exit = 0;
if ($errors) {
foreach ($errors as $className => $errorMessages) {
$output->write("<error>[Mapping] FAIL - The entity-class '" . $className . "' mapping is invalid:</error>\n");
$output->writeln("<error>[Mapping] FAIL - The entity-class '" . $className . "' mapping is invalid:</error>");
foreach ($errorMessages as $errorMessage) {
$output->write('* ' . $errorMessage . "\n");
$output->writeln('* ' . $errorMessage);
}
$output->write("\n");
$output->writeln('');
}
$exit += 1;
} else {
$output->write('<info>[Mapping] OK - The mapping files are correct.</info>' . "\n");
$output->writeln('<info>[Mapping] OK - The mapping files are correct.</info>');
}
if (!$validator->schemaInSyncWithMetadata()) {
$output->write('<error>[Database] FAIL - The database schema is not in sync with the current mapping file.</error>' . "\n");
$output->writeln('<error>[Database] FAIL - The database schema is not in sync with the current mapping file.</error>');
$exit += 2;
} else {
$output->write('<info>[Database] OK - The database schema is in sync with the mapping files.</info>' . "\n");
$output->writeln('<info>[Database] OK - The database schema is in sync with the mapping files.</info>');
}
return $exit;

View File

@ -21,6 +21,7 @@ namespace Doctrine\ORM\Tools\Console;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Helper\HelperSet;
use Doctrine\ORM\Mapping\Version;
class ConsoleRunner
{
@ -28,12 +29,12 @@ class ConsoleRunner
* Run console with the given helperset.
*
* @param \Symfony\Component\Console\Helper\HelperSet $helperSet
* @param \Symfony\Component\Console\Command\Command[] $commands
* @param \Symfony\Component\Console\Command\Command[] $commands
* @return void
*/
static public function run(HelperSet $helperSet, $commands = array())
{
$cli = new Application('Doctrine Command Line Interface', \Doctrine\ORM\Version::VERSION);
$cli = new Application('Doctrine Command Line Interface', Version::VERSION);
$cli->setCatchExceptions(true);
$cli->setHelperSet($helperSet);
self::addCommands($cli);

View File

@ -25,7 +25,7 @@ use Symfony\Component\Console\Helper\Helper,
/**
* Doctrine CLI Connection Helper.
*
*
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
@ -44,7 +44,7 @@ class EntityManagerHelper extends Helper
/**
* Constructor
*
* @param \Doctrine\DBAL\Connection $connection Doctrine Database Connection
* @param \Doctrine\ORM\EntityManager $em
*/
public function __construct(EntityManager $em)
{

View File

@ -32,41 +32,45 @@ namespace Doctrine\ORM\Tools\Console;
*/
class MetadataFilter extends \FilterIterator implements \Countable
{
private $filter = array();
/**
* Filter Metadatas by one or more filter options.
*
* @param array $metadatas
* @param array $metadatas
* @param array|string $filter
*
* @return array
*/
static public function filter(array $metadatas, $filter)
{
$metadatas = new MetadataFilter(new \ArrayIterator($metadatas), $filter);
return iterator_to_array($metadatas);
}
private $_filter = array();
public function __construct(\ArrayIterator $metadata, $filter)
{
$this->_filter = (array)$filter;
$this->filter = (array) $filter;
parent::__construct($metadata);
}
public function accept()
{
if (count($this->_filter) == 0) {
if (count($this->filter) == 0) {
return true;
}
$it = $this->getInnerIterator();
$metadata = $it->current();
foreach ($this->_filter as $filter) {
foreach ($this->filter as $filter) {
if (strpos($metadata->name, $filter) !== false) {
return true;
}
}
return false;
}

View File

@ -20,13 +20,14 @@
namespace Doctrine\ORM\Tools;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\ORM\Tools\Export\Driver\AbstractExporter;
use Doctrine\Common\Util\Inflector;
use Doctrine\DBAL\Types\Type;
use Symfony\Component\Yaml\Yaml;
/**
* Class to help with converting Doctrine 1 schema files to Doctrine 2 mapping files
*
*
*
* @link www.doctrine-project.org
* @since 2.0
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
@ -35,7 +36,8 @@ use Doctrine\Common\Util\Inflector;
*/
class ConvertDoctrine1Schema
{
private $_legacyTypeMap = array(
private $from;
private $legacyTypeMap = array(
// TODO: This list may need to be updated
'clob' => 'text',
'timestamp' => 'datetime',
@ -51,7 +53,7 @@ class ConvertDoctrine1Schema
*/
public function __construct($from)
{
$this->_from = (array) $from;
$this->from = (array) $from;
}
/**
@ -63,38 +65,38 @@ class ConvertDoctrine1Schema
public function getMetadata()
{
$schema = array();
foreach ($this->_from as $path) {
foreach ($this->from as $path) {
if (is_dir($path)) {
$files = glob($path . '/*.yml');
foreach ($files as $file) {
$schema = array_merge($schema, (array) \Symfony\Component\Yaml\Yaml::parse($file));
$schema = array_merge($schema, (array) Yaml::parse($file));
}
} else {
$schema = array_merge($schema, (array) \Symfony\Component\Yaml\Yaml::parse($path));
$schema = array_merge($schema, (array) Yaml::parse($path));
}
}
$metadatas = array();
foreach ($schema as $className => $mappingInformation) {
$metadatas[] = $this->_convertToClassMetadataInfo($className, $mappingInformation);
$metadatas[] = $this->convertToClassMetadataInfo($className, $mappingInformation);
}
return $metadatas;
}
private function _convertToClassMetadataInfo($className, $mappingInformation)
private function convertToClassMetadataInfo($className, $mappingInformation)
{
$metadata = new ClassMetadataInfo($className);
$this->_convertTableName($className, $mappingInformation, $metadata);
$this->_convertColumns($className, $mappingInformation, $metadata);
$this->_convertIndexes($className, $mappingInformation, $metadata);
$this->_convertRelations($className, $mappingInformation, $metadata);
$this->convertTableName($className, $mappingInformation, $metadata);
$this->convertColumns($className, $mappingInformation, $metadata);
$this->convertIndexes($className, $mappingInformation, $metadata);
$this->convertRelations($className, $mappingInformation, $metadata);
return $metadata;
}
private function _convertTableName($className, array $model, ClassMetadataInfo $metadata)
private function convertTableName($className, array $model, ClassMetadataInfo $metadata)
{
if (isset($model['tableName']) && $model['tableName']) {
$e = explode('.', $model['tableName']);
@ -108,13 +110,13 @@ class ConvertDoctrine1Schema
}
}
private function _convertColumns($className, array $model, ClassMetadataInfo $metadata)
private function convertColumns($className, array $model, ClassMetadataInfo $metadata)
{
$id = false;
if (isset($model['columns']) && $model['columns']) {
foreach ($model['columns'] as $name => $column) {
$fieldMapping = $this->_convertColumn($className, $name, $column, $metadata);
$fieldMapping = $this->convertColumn($className, $name, $column, $metadata);
if (isset($fieldMapping['id']) && $fieldMapping['id']) {
$id = true;
@ -134,46 +136,56 @@ class ConvertDoctrine1Schema
}
}
private function _convertColumn($className, $name, $column, ClassMetadataInfo $metadata)
private function convertColumn($className, $name, $column, ClassMetadataInfo $metadata)
{
if (is_string($column)) {
$string = $column;
$column = array();
$column['type'] = $string;
}
if ( ! isset($column['name'])) {
$column['name'] = $name;
}
// check if a column alias was used (column_name as field_name)
if (preg_match("/(\w+)\sas\s(\w+)/i", $column['name'], $matches)) {
$name = $matches[1];
$column['name'] = $name;
$column['alias'] = $matches[2];
}
if (preg_match("/([a-zA-Z]+)\(([0-9]+)\)/", $column['type'], $matches)) {
$column['type'] = $matches[1];
$column['length'] = $matches[2];
}
$column['type'] = strtolower($column['type']);
// check if legacy column type (1.x) needs to be mapped to a 2.0 one
if (isset($this->_legacyTypeMap[$column['type']])) {
$column['type'] = $this->_legacyTypeMap[$column['type']];
if (isset($this->legacyTypeMap[$column['type']])) {
$column['type'] = $this->legacyTypeMap[$column['type']];
}
if ( ! \Doctrine\DBAL\Types\Type::hasType($column['type'])) {
if ( ! Type::hasType($column['type'])) {
throw ToolsException::couldNotMapDoctrine1Type($column['type']);
}
$fieldMapping = array();
if (isset($column['primary'])) {
$fieldMapping['id'] = true;
}
$fieldMapping['fieldName'] = isset($column['alias']) ? $column['alias'] : $name;
$fieldMapping['columnName'] = $column['name'];
$fieldMapping['type'] = $column['type'];
if (isset($column['length'])) {
$fieldMapping['length'] = $column['length'];
}
$allowed = array('precision', 'scale', 'unique', 'options', 'notnull', 'version');
foreach ($column as $key => $value) {
if (in_array($key, $allowed)) {
$fieldMapping[$key] = $value;
@ -184,88 +196,97 @@ class ConvertDoctrine1Schema
if (isset($column['autoincrement'])) {
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
} else if (isset($column['sequence'])) {
} elseif (isset($column['sequence'])) {
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE);
$definition = array(
'sequenceName' => is_array($column['sequence']) ? $column['sequence']['name']:$column['sequence']
);
if (isset($column['sequence']['size'])) {
$definition['allocationSize'] = $column['sequence']['size'];
}
if (isset($column['sequence']['value'])) {
$definition['initialValue'] = $column['sequence']['value'];
}
$metadata->setSequenceGeneratorDefinition($definition);
}
return $fieldMapping;
}
private function _convertIndexes($className, array $model, ClassMetadataInfo $metadata)
private function convertIndexes($className, array $model, ClassMetadataInfo $metadata)
{
if (isset($model['indexes']) && $model['indexes']) {
foreach ($model['indexes'] as $name => $index) {
$type = (isset($index['type']) && $index['type'] == 'unique')
? 'uniqueConstraints' : 'indexes';
if (empty($model['indexes'])) {
return;
}
$metadata->table[$type][$name] = array(
'columns' => $index['fields']
);
}
foreach ($model['indexes'] as $name => $index) {
$type = (isset($index['type']) && $index['type'] == 'unique')
? 'uniqueConstraints' : 'indexes';
$metadata->table[$type][$name] = array(
'columns' => $index['fields']
);
}
}
private function _convertRelations($className, array $model, ClassMetadataInfo $metadata)
private function convertRelations($className, array $model, ClassMetadataInfo $metadata)
{
if (isset($model['relations']) && $model['relations']) {
foreach ($model['relations'] as $name => $relation) {
if ( ! isset($relation['alias'])) {
$relation['alias'] = $name;
}
if ( ! isset($relation['class'])) {
$relation['class'] = $name;
}
if ( ! isset($relation['local'])) {
$relation['local'] = Inflector::tableize($relation['class']);
}
if ( ! isset($relation['foreign'])) {
$relation['foreign'] = 'id';
}
if ( ! isset($relation['foreignAlias'])) {
$relation['foreignAlias'] = $className;
}
if (empty($model['relations'])) {
return;
}
if (isset($relation['refClass'])) {
$type = 'many';
$foreignType = 'many';
$joinColumns = array();
} else {
$type = isset($relation['type']) ? $relation['type'] : 'one';
$foreignType = isset($relation['foreignType']) ? $relation['foreignType'] : 'many';
$joinColumns = array(
array(
'name' => $relation['local'],
'referencedColumnName' => $relation['foreign'],
'onDelete' => isset($relation['onDelete']) ? $relation['onDelete'] : null,
)
);
}
if ($type == 'one' && $foreignType == 'one') {
$method = 'mapOneToOne';
} else if ($type == 'many' && $foreignType == 'many') {
$method = 'mapManyToMany';
} else {
$method = 'mapOneToMany';
}
$associationMapping = array();
$associationMapping['fieldName'] = $relation['alias'];
$associationMapping['targetEntity'] = $relation['class'];
$associationMapping['mappedBy'] = $relation['foreignAlias'];
$associationMapping['joinColumns'] = $joinColumns;
$metadata->$method($associationMapping);
foreach ($model['relations'] as $name => $relation) {
if ( ! isset($relation['alias'])) {
$relation['alias'] = $name;
}
if ( ! isset($relation['class'])) {
$relation['class'] = $name;
}
if ( ! isset($relation['local'])) {
$relation['local'] = Inflector::tableize($relation['class']);
}
if ( ! isset($relation['foreign'])) {
$relation['foreign'] = 'id';
}
if ( ! isset($relation['foreignAlias'])) {
$relation['foreignAlias'] = $className;
}
if (isset($relation['refClass'])) {
$type = 'many';
$foreignType = 'many';
$joinColumns = array();
} else {
$type = isset($relation['type']) ? $relation['type'] : 'one';
$foreignType = isset($relation['foreignType']) ? $relation['foreignType'] : 'many';
$joinColumns = array(
array(
'name' => $relation['local'],
'referencedColumnName' => $relation['foreign'],
'onDelete' => isset($relation['onDelete']) ? $relation['onDelete'] : null,
)
);
}
if ($type == 'one' && $foreignType == 'one') {
$method = 'mapOneToOne';
} elseif ($type == 'many' && $foreignType == 'many') {
$method = 'mapManyToMany';
} else {
$method = 'mapOneToMany';
}
$associationMapping = array();
$associationMapping['fieldName'] = $relation['alias'];
$associationMapping['targetEntity'] = $relation['class'];
$associationMapping['mappedBy'] = $relation['foreignAlias'];
$associationMapping['joinColumns'] = $joinColumns;
$metadata->$method($associationMapping);
}
}
}

View File

@ -19,6 +19,7 @@
namespace Doctrine\ORM\Tools;
use Doctrine\Common\Persistence\Proxy;
use Doctrine\ORM\Event\OnFlushEventArgs;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\PersistentCollection;
@ -73,11 +74,13 @@ class DebugUnitOfWorkListener
fwrite($fh, "Flush Operation [".$this->context."] - Dumping identity map:\n");
foreach ($identityMap as $className => $map) {
fwrite($fh, "Class: ". $className . "\n");
foreach ($map as $entity) {
fwrite($fh, " Entity: " . $this->getIdString($entity, $uow) . " " . spl_object_hash($entity)."\n");
fwrite($fh, " Associations:\n");
$cm = $em->getClassMetadata($className);
foreach ($cm->associationMappings as $field => $assoc) {
fwrite($fh, " " . $field . " ");
$value = $cm->reflFields[$field]->getValue($entity);
@ -86,7 +89,7 @@ class DebugUnitOfWorkListener
if ($value === null) {
fwrite($fh, " NULL\n");
} else {
if ($value instanceof Proxy && !$value->__isInitialized__) {
if ($value instanceof Proxy && !$value->__isInitialized()) {
fwrite($fh, "[PROXY] ");
}
@ -96,8 +99,9 @@ class DebugUnitOfWorkListener
$initialized = !($value instanceof PersistentCollection) || $value->isInitialized();
if ($value === null) {
fwrite($fh, " NULL\n");
} else if ($initialized) {
} elseif ($initialized) {
fwrite($fh, "[INITIALIZED] " . $this->getType($value). " " . count($value) . " elements\n");
foreach ($value as $obj) {
fwrite($fh, " " . $this->getIdString($obj, $uow) . " " . spl_object_hash($obj)."\n");
}
@ -111,6 +115,7 @@ class DebugUnitOfWorkListener
}
}
}
fclose($fh);
}
@ -118,17 +123,19 @@ class DebugUnitOfWorkListener
{
if (is_object($var)) {
$refl = new \ReflectionObject($var);
return $refl->getShortname();
} else {
return gettype($var);
}
return gettype($var);
}
private function getIdString($entity, $uow)
private function getIdString($entity, UnitOfWork $uow)
{
if ($uow->isInIdentityMap($entity)) {
$ids = $uow->getEntityIdentifier($entity);
$idstring = "";
foreach ($ids as $k => $v) {
$idstring .= $k."=".$v;
}
@ -137,13 +144,14 @@ class DebugUnitOfWorkListener
}
$state = $uow->getEntityState($entity);
if ($state == UnitOfWork::STATE_NEW) {
$idstring .= " [NEW]";
} else if ($state == UnitOfWork::STATE_REMOVED) {
} elseif ($state == UnitOfWork::STATE_REMOVED) {
$idstring .= " [REMOVED]";
} else if ($state == UnitOfWork::STATE_MANAGED) {
} elseif ($state == UnitOfWork::STATE_MANAGED) {
$idstring .= " [MANAGED]";
} else if ($state == UnitOfwork::STATE_DETACHED) {
} elseif ($state == UnitOfwork::STATE_DETACHED) {
$idstring .= " [DETACHED]";
}

View File

@ -19,8 +19,8 @@
namespace Doctrine\ORM\Tools;
use Doctrine\Common\Persistence\Mapping\StaticReflectionService;
use Doctrine\ORM\Mapping\ClassMetadataFactory;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
/**
* The DisconnectedClassMetadataFactory is used to create ClassMetadataInfo objects
@ -28,7 +28,7 @@ use Doctrine\ORM\Mapping\ClassMetadataInfo;
* load some mapping information and use it to do things like generate code
* from the mapping information.
*
*
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
@ -40,6 +40,6 @@ class DisconnectedClassMetadataFactory extends ClassMetadataFactory
{
public function getReflectionService()
{
return new \Doctrine\Common\Persistence\Mapping\StaticReflectionService;
return new StaticReflectionService();
}
}

View File

@ -317,7 +317,7 @@ public function __construct()
if ($this->isNew) {
file_put_contents($path, $this->generateEntityClass($metadata));
// If entity exists and we're allowed to update the entity class
} else if ( ! $this->isNew && $this->updateEntityIfExists) {
} elseif ( ! $this->isNew && $this->updateEntityIfExists) {
file_put_contents($path, $this->generateUpdatedEntityClass($metadata, $path));
}
}
@ -345,6 +345,7 @@ public function __construct()
);
$code = str_replace($placeHolders, $replacements, self::$classTemplate);
return str_replace('<spaces>', $this->spaces, $code);
}
@ -565,6 +566,7 @@ public function __construct()
$inNamespace = false;
$inClass = false;
for ($i = 0; $i < count($tokens); $i++) {
$token = $tokens[$i];
if (in_array($token[0], array(T_WHITESPACE, T_COMMENT, T_DOC_COMMENT))) {
@ -574,7 +576,7 @@ public function __construct()
if ($inNamespace) {
if ($token[0] == T_NS_SEPARATOR || $token[0] == T_STRING) {
$lastSeenNamespace .= $token[1];
} else if (is_string($token) && in_array($token, array(';', '{'))) {
} elseif (is_string($token) && in_array($token, array(';', '{'))) {
$inNamespace = false;
}
}
@ -589,15 +591,15 @@ public function __construct()
if ($token[0] == T_NAMESPACE) {
$lastSeenNamespace = "";
$inNamespace = true;
} else if ($token[0] == T_CLASS) {
} elseif ($token[0] == T_CLASS) {
$inClass = true;
} else if ($token[0] == T_FUNCTION) {
} elseif ($token[0] == T_FUNCTION) {
if ($tokens[$i+2][0] == T_STRING) {
$this->staticReflection[$lastSeenClass]['methods'][] = $tokens[$i+2][1];
} else if ($tokens[$i+2] == "&" && $tokens[$i+3][0] == T_STRING) {
} elseif ($tokens[$i+2] == "&" && $tokens[$i+3][0] == T_STRING) {
$this->staticReflection[$lastSeenClass]['methods'][] = $tokens[$i+3][1];
}
} else if (in_array($token[0], array(T_VAR, T_PUBLIC, T_PRIVATE, T_PROTECTED)) && $tokens[$i+2][0] != T_FUNCTION) {
} elseif (in_array($token[0], array(T_VAR, T_PUBLIC, T_PRIVATE, T_PROTECTED)) && $tokens[$i+2][0] != T_FUNCTION) {
$this->staticReflection[$lastSeenClass]['properties'][] = substr($tokens[$i+2][1], 1);
}
}
@ -624,6 +626,7 @@ public function __construct()
if ($this->extendsClass()) {
// don't generate method if its already on the base class.
$reflClass = new \ReflectionClass($this->getClassToExtend());
if ($reflClass->hasMethod($method)) {
return true;
}
@ -672,7 +675,7 @@ public function __construct()
{
$lines = array();
$lines[] = '/**';
$lines[] = ' * '.$metadata->name;
$lines[] = ' * ' . $this->getClassName($metadata);
if ($this->generateAnnotations) {
$lines[] = ' *';
@ -805,7 +808,7 @@ public function __construct()
if ($code = $this->generateEntityStubMethod($metadata, 'get', $associationMapping['fieldName'], $associationMapping['targetEntity'])) {
$methods[] = $code;
}
} else if ($associationMapping['type'] & ClassMetadataInfo::TO_MANY) {
} elseif ($associationMapping['type'] & ClassMetadataInfo::TO_MANY) {
if ($code = $this->generateEntityStubMethod($metadata, 'add', $associationMapping['fieldName'], $associationMapping['targetEntity'])) {
$methods[] = $code;
}
@ -826,17 +829,20 @@ public function __construct()
if (isset($associationMapping['id']) && $associationMapping['id']) {
return false;
}
if (isset($associationMapping['joinColumns'])) {
$joinColumns = $associationMapping['joinColumns'];
} else {
//@todo thereis no way to retreive targetEntity metadata
//@todo there is no way to retrieve targetEntity metadata
$joinColumns = array();
}
foreach ($joinColumns as $joinColumn) {
if(isset($joinColumn['nullable']) && !$joinColumn['nullable']) {
return false;
}
}
return true;
}
@ -902,7 +908,7 @@ public function __construct()
}
if ($this->hasMethod($methodName, $metadata)) {
return;
return '';
}
$this->staticReflection[$metadata->name]['methods'][] = $methodName;
@ -936,7 +942,7 @@ public function __construct()
private function generateLifecycleCallbackMethod($name, $methodName, $metadata)
{
if ($this->hasMethod($methodName, $metadata)) {
return;
return '';
}
$this->staticReflection[$metadata->name]['methods'][] = $methodName;
@ -1126,7 +1132,7 @@ public function __construct()
{
$lines = array();
$lines[] = $this->spaces . '/**';
$lines[] = $this->spaces . ' * @var ' . $this->getType($fieldMapping['type']) . ' $' . $fieldMapping['fieldName'];
$lines[] = $this->spaces . ' * @var ' . $this->getType($fieldMapping['type']);
if ($this->generateAnnotations) {
$lines[] = $this->spaces . ' *';

View File

@ -22,7 +22,7 @@ namespace Doctrine\ORM\Tools;
/**
* Class to generate entity repository classes
*
*
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
@ -58,6 +58,7 @@ class <className> extends EntityRepository
'<namespace>' => $this->generateEntityRepositoryNamespace($fullClassName),
'<className>' => $className
);
return str_replace(array_keys($variables), array_values($variables), self::$_template);
}

View File

@ -19,6 +19,7 @@
namespace Doctrine\ORM\Tools\Event;
use Doctrine\Common\EventArgs;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\ORM\EntityManager;
@ -30,33 +31,34 @@ use Doctrine\ORM\EntityManager;
* @since 1.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class GenerateSchemaEventArgs extends \Doctrine\Common\EventArgs
class GenerateSchemaEventArgs extends EventArgs
{
private $_em = null;
private $_schema = null;
private $em;
private $schema;
/**
* @param ClassMetadata $classMetadata
* @param Schema $schema
* @param Table $classTable
* @param EntityManager $em
* @param Schema $schema
*/
public function __construct(EntityManager $em, Schema $schema)
{
$this->_em = $em;
$this->_schema = $schema;
$this->em = $em;
$this->schema = $schema;
}
/**
* @return EntityManager
*/
public function getEntityManager() {
return $this->_em;
public function getEntityManager()
{
return $this->em;
}
/**
* @return Schema
*/
public function getSchema() {
return $this->_schema;
public function getSchema()
{
return $this->schema;
}
}

View File

@ -18,6 +18,7 @@
*/
namespace Doctrine\ORM\Tools\Event;
use Doctrine\Common\EventArgs;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;
@ -30,42 +31,45 @@ use Doctrine\DBAL\Schema\Table;
* @since 1.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class GenerateSchemaTableEventArgs extends \Doctrine\Common\EventArgs
class GenerateSchemaTableEventArgs extends EventArgs
{
private $_classMetadata = null;
private $_schema = null;
private $_classTable = null;
private $classMetadata;
private $schema;
private $classTable;
/**
* @param ClassMetadata $classMetadata
* @param Schema $schema
* @param Table $classTable
* @param Schema $schema
* @param Table $classTable
*/
public function __construct(ClassMetadata $classMetadata, Schema $schema, Table $classTable)
{
$this->_classMetadata = $classMetadata;
$this->_schema = $schema;
$this->_classTable = $classTable;
$this->classMetadata = $classMetadata;
$this->schema = $schema;
$this->classTable = $classTable;
}
/**
* @return ClassMetadata
*/
public function getClassMetadata() {
return $this->_classMetadata;
public function getClassMetadata()
{
return $this->classMetadata;
}
/**
* @return Schema
*/
public function getSchema() {
return $this->_schema;
public function getSchema()
{
return $this->schema;
}
/**
* @return Table
*/
public function getClassTable() {
return $this->_classTable;
public function getClassTable()
{
return $this->classTable;
}
}

View File

@ -20,13 +20,11 @@
namespace Doctrine\ORM\Tools\Export;
use Doctrine\ORM\Tools\Export\ExportException;
use Doctrine\ORM\EntityManager;
/**
* Class used for converting your mapping information between the
* supported formats: yaml, xml, and php/annotation.
*
*
* @link www.doctrine-project.org
* @since 2.0
* @author Jonathan Wage <jonwage@gmail.com>
@ -57,7 +55,8 @@ class ClassMetadataExporter
*
* @param string $type The type to get (yml, xml, etc.)
* @param string $source The directory where the exporter will export to
* @return AbstractExporter $exporter
*
* @return Driver\AbstractExporter $exporter
*/
public function getExporter($type, $dest = null)
{

View File

@ -26,7 +26,7 @@ use Doctrine\ORM\Tools\Export\ExportException;
* Abstract base class which is to be used for the Exporter drivers
* which can be found in \Doctrine\ORM\Tools\Export\Driver
*
*
*
* @link www.doctrine-project.org
* @since 2.0
* @author Jonathan Wage <jonwage@gmail.com>
@ -151,63 +151,49 @@ abstract class AbstractExporter
protected function _getInheritanceTypeString($type)
{
switch ($type)
{
switch ($type) {
case ClassMetadataInfo::INHERITANCE_TYPE_NONE:
return 'NONE';
break;
case ClassMetadataInfo::INHERITANCE_TYPE_JOINED:
return 'JOINED';
break;
case ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_TABLE:
return 'SINGLE_TABLE';
break;
case ClassMetadataInfo::INHERITANCE_TYPE_TABLE_PER_CLASS:
return 'PER_CLASS';
break;
}
}
protected function _getChangeTrackingPolicyString($policy)
{
switch ($policy)
{
switch ($policy) {
case ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT:
return 'DEFERRED_IMPLICIT';
break;
case ClassMetadataInfo::CHANGETRACKING_DEFERRED_EXPLICIT:
return 'DEFERRED_EXPLICIT';
break;
case ClassMetadataInfo::CHANGETRACKING_NOTIFY:
return 'NOTIFY';
break;
}
}
protected function _getIdGeneratorTypeString($type)
{
switch ($type)
{
switch ($type) {
case ClassMetadataInfo::GENERATOR_TYPE_AUTO:
return 'AUTO';
break;
case ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE:
return 'SEQUENCE';
break;
case ClassMetadataInfo::GENERATOR_TYPE_TABLE:
return 'TABLE';
break;
case ClassMetadataInfo::GENERATOR_TYPE_IDENTITY:
return 'IDENTITY';
break;
}
}
}

View File

@ -25,7 +25,7 @@ use Doctrine\ORM\Tools\EntityGenerator;
/**
* ClassMetadata exporter for PHP classes with annotations
*
*
*
* @link www.doctrine-project.org
* @since 2.0
* @author Jonathan Wage <jonwage@gmail.com>
@ -47,6 +47,7 @@ class AnnotationExporter extends AbstractExporter
if ( ! $this->_entityGenerator) {
throw new \RuntimeException('For the AnnotationExporter you must set an EntityGenerator instance with the setEntityGenerator() method.');
}
$this->_entityGenerator->setGenerateAnnotations(true);
$this->_entityGenerator->setGenerateStubMethods(false);
$this->_entityGenerator->setRegenerateEntityIfExists(false);

View File

@ -24,7 +24,7 @@ use Doctrine\ORM\Mapping\ClassMetadataInfo;
/**
* ClassMetadata exporter for PHP code
*
*
*
* @link www.doctrine-project.org
* @since 2.0
* @author Jonathan Wage <jonwage@gmail.com>
@ -120,7 +120,7 @@ class PhpExporter extends AbstractExporter
);
$associationMappingArray = array_merge($associationMappingArray, $oneToOneMappingArray);
} else if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) {
} elseif ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) {
$method = 'mapOneToMany';
$potentialAssociationMappingIndexes = array(
'mappedBy',
@ -133,7 +133,7 @@ class PhpExporter extends AbstractExporter
}
}
$associationMappingArray = array_merge($associationMappingArray, $oneToManyMappingArray);
} else if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) {
} elseif ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) {
$method = 'mapManyToMany';
$potentialAssociationMappingIndexes = array(
'mappedBy',

View File

@ -24,7 +24,6 @@ use Doctrine\ORM\Mapping\ClassMetadataInfo;
/**
* ClassMetadata exporter for Doctrine XML mapping files
*
*
* @link www.doctrine-project.org
* @since 2.0
* @author Jonathan Wage <jonwage@gmail.com>
@ -79,6 +78,7 @@ class XmlExporter extends AbstractExporter
$discriminatorColumnXml = $root->addChild('discriminator-column');
$discriminatorColumnXml->addAttribute('name', $metadata->discriminatorColumn['name']);
$discriminatorColumnXml->addAttribute('type', $metadata->discriminatorColumn['type']);
if (isset($metadata->discriminatorColumn['length'])) {
$discriminatorColumnXml->addAttribute('length', $metadata->discriminatorColumn['length']);
}
@ -86,6 +86,7 @@ class XmlExporter extends AbstractExporter
if ($metadata->discriminatorMap) {
$discriminatorMapXml = $root->addChild('discriminator-map');
foreach ($metadata->discriminatorMap as $value => $className) {
$discriminatorMappingXml = $discriminatorMapXml->addChild('discriminator-mapping');
$discriminatorMappingXml->addAttribute('value', $value);
@ -94,6 +95,7 @@ class XmlExporter extends AbstractExporter
}
$trackingPolicy = $this->_getChangeTrackingPolicyString($metadata->changeTrackingPolicy);
if ( $trackingPolicy != 'DEFERRED_IMPLICIT') {
$root->addChild('change-tracking-policy', $trackingPolicy);
}
@ -137,12 +139,15 @@ class XmlExporter extends AbstractExporter
$idXml = $root->addChild('id');
$idXml->addAttribute('name', $field['fieldName']);
$idXml->addAttribute('type', $field['type']);
if (isset($field['columnName'])) {
$idXml->addAttribute('column', $field['columnName']);
}
if (isset($field['associationKey']) && $field['associationKey']) {
$idXml->addAttribute('association-key', 'true');
}
if ($idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
$generatorXml = $idXml->addChild('generator');
$generatorXml->addAttribute('strategy', $idGeneratorType);
@ -155,57 +160,70 @@ class XmlExporter extends AbstractExporter
$fieldXml = $root->addChild('field');
$fieldXml->addAttribute('name', $field['fieldName']);
$fieldXml->addAttribute('type', $field['type']);
if (isset($field['columnName'])) {
$fieldXml->addAttribute('column', $field['columnName']);
}
if (isset($field['length'])) {
$fieldXml->addAttribute('length', $field['length']);
}
if (isset($field['precision'])) {
$fieldXml->addAttribute('precision', $field['precision']);
}
if (isset($field['scale'])) {
$fieldXml->addAttribute('scale', $field['scale']);
}
if (isset($field['unique']) && $field['unique']) {
$fieldXml->addAttribute('unique', $field['unique']);
}
if (isset($field['options'])) {
$optionsXml = $fieldXml->addChild('options');
foreach ($field['options'] as $key => $value) {
$optionsXml->addAttribute($key, $value);
}
}
if (isset($field['version'])) {
$fieldXml->addAttribute('version', $field['version']);
}
if (isset($field['columnDefinition'])) {
$fieldXml->addAttribute('column-definition', $field['columnDefinition']);
}
if (isset($field['nullable'])) {
$fieldXml->addAttribute('nullable', $field['nullable'] ? 'true' : 'false');
}
}
}
$orderMap = array(
ClassMetadataInfo::ONE_TO_ONE,
ClassMetadataInfo::ONE_TO_MANY,
ClassMetadataInfo::MANY_TO_ONE,
ClassMetadataInfo::MANY_TO_MANY,
);
uasort($metadata->associationMappings, function($m1, $m2)use(&$orderMap){
$a1 = array_search($m1['type'],$orderMap);
$a2 = array_search($m2['type'],$orderMap);
uasort($metadata->associationMappings, function($m1, $m2) use (&$orderMap){
$a1 = array_search($m1['type'], $orderMap);
$a2 = array_search($m2['type'], $orderMap);
return strcmp($a1, $a2);
});
foreach ($metadata->associationMappings as $name => $associationMapping) {
foreach ($metadata->associationMappings as $associationMapping) {
if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_ONE) {
$associationMappingXml = $root->addChild('one-to-one');
} else if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_ONE) {
} elseif ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_ONE) {
$associationMappingXml = $root->addChild('many-to-one');
} else if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) {
} elseif ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) {
$associationMappingXml = $root->addChild('one-to-many');
} else if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) {
} elseif ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) {
$associationMappingXml = $root->addChild('many-to-many');
}
@ -215,41 +233,53 @@ class XmlExporter extends AbstractExporter
if (isset($associationMapping['mappedBy'])) {
$associationMappingXml->addAttribute('mapped-by', $associationMapping['mappedBy']);
}
if (isset($associationMapping['inversedBy'])) {
$associationMappingXml->addAttribute('inversed-by', $associationMapping['inversedBy']);
}
if (isset($associationMapping['indexBy'])) {
$associationMappingXml->addAttribute('index-by', $associationMapping['indexBy']);
}
if (isset($associationMapping['orphanRemoval']) && $associationMapping['orphanRemoval']!==false) {
if (isset($associationMapping['orphanRemoval']) && $associationMapping['orphanRemoval'] !== false) {
$associationMappingXml->addAttribute('orphan-removal', 'true');
}
if (isset($associationMapping['joinTable']) && $associationMapping['joinTable']) {
$joinTableXml = $associationMappingXml->addChild('join-table');
$joinTableXml->addAttribute('name', $associationMapping['joinTable']['name']);
$joinColumnsXml = $joinTableXml->addChild('join-columns');
foreach ($associationMapping['joinTable']['joinColumns'] as $joinColumn) {
$joinColumnXml = $joinColumnsXml->addChild('join-column');
$joinColumnXml->addAttribute('name', $joinColumn['name']);
$joinColumnXml->addAttribute('referenced-column-name', $joinColumn['referencedColumnName']);
if (isset($joinColumn['onDelete'])) {
$joinColumnXml->addAttribute('on-delete', $joinColumn['onDelete']);
}
}
$inverseJoinColumnsXml = $joinTableXml->addChild('inverse-join-columns');
foreach ($associationMapping['joinTable']['inverseJoinColumns'] as $inverseJoinColumn) {
$inverseJoinColumnXml = $inverseJoinColumnsXml->addChild('join-column');
$inverseJoinColumnXml->addAttribute('name', $inverseJoinColumn['name']);
$inverseJoinColumnXml->addAttribute('referenced-column-name', $inverseJoinColumn['referencedColumnName']);
if (isset($inverseJoinColumn['onDelete'])) {
$inverseJoinColumnXml->addAttribute('on-delete', $inverseJoinColumn['onDelete']);
}
if (isset($inverseJoinColumn['columnDefinition'])) {
$inverseJoinColumnXml->addAttribute('column-definition', $inverseJoinColumn['columnDefinition']);
}
if (isset($inverseJoinColumn['nullable'])) {
$inverseJoinColumnXml->addAttribute('nullable', $inverseJoinColumn['nullable']);
}
if (isset($inverseJoinColumn['orderBy'])) {
$inverseJoinColumnXml->addAttribute('order-by', $inverseJoinColumn['orderBy']);
}
@ -257,16 +287,20 @@ class XmlExporter extends AbstractExporter
}
if (isset($associationMapping['joinColumns'])) {
$joinColumnsXml = $associationMappingXml->addChild('join-columns');
foreach ($associationMapping['joinColumns'] as $joinColumn) {
$joinColumnXml = $joinColumnsXml->addChild('join-column');
$joinColumnXml->addAttribute('name', $joinColumn['name']);
$joinColumnXml->addAttribute('referenced-column-name', $joinColumn['referencedColumnName']);
if (isset($joinColumn['onDelete'])) {
$joinColumnXml->addAttribute('on-delete', $joinColumn['onDelete']);
}
if (isset($joinColumn['columnDefinition'])) {
$joinColumnXml->addAttribute('column-definition', $joinColumn['columnDefinition']);
}
if (isset($joinColumn['nullable'])) {
$joinColumnXml->addAttribute('nullable', $joinColumn['nullable']);
}
@ -274,6 +308,7 @@ class XmlExporter extends AbstractExporter
}
if (isset($associationMapping['orderBy'])) {
$orderByXml = $associationMappingXml->addChild('order-by');
foreach ($associationMapping['orderBy'] as $name => $direction) {
$orderByFieldXml = $orderByXml->addChild('order-by-field');
$orderByFieldXml->addAttribute('name', $name);
@ -281,26 +316,34 @@ class XmlExporter extends AbstractExporter
}
}
$cascade = array();
if ($associationMapping['isCascadeRemove']) {
$cascade[] = 'cascade-remove';
}
if ($associationMapping['isCascadePersist']) {
$cascade[] = 'cascade-persist';
}
if ($associationMapping['isCascadeRefresh']) {
$cascade[] = 'cascade-refresh';
}
if ($associationMapping['isCascadeMerge']) {
$cascade[] = 'cascade-merge';
}
if ($associationMapping['isCascadeDetach']) {
$cascade[] = 'cascade-detach';
}
if (count($cascade) === 5) {
$cascade = array('cascade-all');
}
if ($cascade) {
$cascadeXml = $associationMappingXml->addChild('cascade');
foreach ($cascade as $type) {
$cascadeXml->addChild($type);
}
@ -309,6 +352,7 @@ class XmlExporter extends AbstractExporter
if (isset($metadata->lifecycleCallbacks) && count($metadata->lifecycleCallbacks)>0) {
$lifecycleCallbacksXml = $root->addChild('lifecycle-callbacks');
foreach ($metadata->lifecycleCallbacks as $name => $methods) {
foreach ($methods as $method) {
$lifecycleCallbackXml = $lifecycleCallbacksXml->addChild('lifecycle-callback');
@ -323,6 +367,7 @@ class XmlExporter extends AbstractExporter
/**
* @param \SimpleXMLElement $simpleXml
*
* @return string $xml
*/
private function _asXml($simpleXml)
@ -331,7 +376,6 @@ class XmlExporter extends AbstractExporter
$dom->loadXML($simpleXml->asXML());
$dom->formatOutput = true;
$result = $dom->saveXML();
return $result;
return $dom->saveXML();
}
}

View File

@ -19,12 +19,13 @@
namespace Doctrine\ORM\Tools\Export\Driver;
use Symfony\Component\Yaml\Yaml;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
/**
* ClassMetadata exporter for Doctrine YAML mapping files
*
*
*
* @link www.doctrine-project.org
* @since 2.0
* @author Jonathan Wage <jonwage@gmail.com>
@ -59,6 +60,7 @@ class YamlExporter extends AbstractExporter
}
$inheritanceType = $metadata->inheritanceType;
if ($inheritanceType !== ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
$array['inheritanceType'] = $this->_getInheritanceTypeString($inheritanceType);
}
@ -92,10 +94,8 @@ class YamlExporter extends AbstractExporter
$ids = array();
foreach ($fieldMappings as $name => $fieldMapping) {
$fieldMapping['column'] = $fieldMapping['columnName'];
unset(
$fieldMapping['columnName'],
$fieldMapping['fieldName']
);
unset($fieldMapping['columnName'], $fieldMapping['fieldName']);
if ($fieldMapping['column'] == $name) {
unset($fieldMapping['column']);
@ -127,24 +127,30 @@ class YamlExporter extends AbstractExporter
foreach ($metadata->associationMappings as $name => $associationMapping) {
$cascade = array();
if ($associationMapping['isCascadeRemove']) {
$cascade[] = 'remove';
}
if ($associationMapping['isCascadePersist']) {
$cascade[] = 'persist';
}
if ($associationMapping['isCascadeRefresh']) {
$cascade[] = 'refresh';
}
if ($associationMapping['isCascadeMerge']) {
$cascade[] = 'merge';
}
if ($associationMapping['isCascadeDetach']) {
$cascade[] = 'detach';
}
if (count($cascade) === 5) {
$cascade = array('all');
}
$associationMappingArray = array(
'targetEntity' => $associationMapping['targetEntity'],
'cascade' => $cascade,
@ -153,12 +159,15 @@ class YamlExporter extends AbstractExporter
if ($associationMapping['type'] & ClassMetadataInfo::TO_ONE) {
$joinColumns = $associationMapping['joinColumns'];
$newJoinColumns = array();
foreach ($joinColumns as $joinColumn) {
$newJoinColumns[$joinColumn['name']]['referencedColumnName'] = $joinColumn['referencedColumnName'];
if (isset($joinColumn['onDelete'])) {
$newJoinColumns[$joinColumn['name']]['onDelete'] = $joinColumn['onDelete'];
}
}
$oneToOneMappingArray = array(
'mappedBy' => $associationMapping['mappedBy'],
'inversedBy' => $associationMapping['inversedBy'],
@ -173,8 +182,7 @@ class YamlExporter extends AbstractExporter
} else {
$array['manyToOne'][$name] = $associationMappingArray;
}
} else if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) {
} elseif ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) {
$oneToManyMappingArray = array(
'mappedBy' => $associationMapping['mappedBy'],
'inversedBy' => $associationMapping['inversedBy'],
@ -184,7 +192,7 @@ class YamlExporter extends AbstractExporter
$associationMappingArray = array_merge($associationMappingArray, $oneToManyMappingArray);
$array['oneToMany'][$name] = $associationMappingArray;
} else if ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) {
} elseif ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) {
$manyToManyMappingArray = array(
'mappedBy' => $associationMapping['mappedBy'],
'inversedBy' => $associationMapping['inversedBy'],
@ -200,6 +208,6 @@ class YamlExporter extends AbstractExporter
$array['lifecycleCallbacks'] = $metadata->lifecycleCallbacks;
}
return \Symfony\Component\Yaml\Yaml::dump(array($metadata->name => $array), 10);
return Yaml::dump(array($metadata->name => $array), 10);
}
}

View File

@ -148,6 +148,7 @@ class Paginator implements \Countable, \IteratorAggregate
$this->count = 0;
}
}
return $this->count;
}
@ -196,6 +197,7 @@ class Paginator implements \Countable, \IteratorAggregate
->getResult($this->query->getHydrationMode())
;
}
return new \ArrayIterator($result);
}

View File

@ -61,6 +61,7 @@ class ResolveTargetEntityListener
public function loadClassMetadata(LoadClassMetadataEventArgs $args)
{
$cm = $args->getClassMetadata();
foreach ($cm->associationMappings as $mapping) {
if (isset($this->resolveTargetEntities[$mapping['targetEntity']])) {
$this->remapAssociation($cm, $mapping);

View File

@ -21,7 +21,10 @@ namespace Doctrine\ORM\Tools;
use Doctrine\ORM\ORMException;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector;
use Doctrine\DBAL\Schema\Visitor\RemoveNamespacedAssets;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping\ClassMetadata;
@ -33,7 +36,6 @@ use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
* The SchemaTool is a tool to create/drop/update database schemas based on
* <tt>ClassMetadata</tt> class descriptors.
*
*
* @link www.doctrine-project.org
* @since 2.0
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
@ -145,12 +147,11 @@ class SchemaTool
continue;
}
$table = $schema->createTable($this->quoteStrategy->getTableName($class, $this->platform));
$columns = array(); // table columns
$table = $schema->createTable($this->quoteStrategy->getTableName($class, $this->platform));
if ($class->isInheritanceTypeSingleTable()) {
$columns = $this->_gatherColumns($class, $table);
$this->_gatherRelationsSql($class, $table, $schema);
$this->gatherColumns($class, $table);
$this->gatherRelationsSql($class, $table, $schema);
// Add the discriminator column
$this->addDiscriminatorColumnDefinition($class, $table);
@ -163,17 +164,17 @@ class SchemaTool
foreach ($class->subClasses as $subClassName) {
$subClass = $this->em->getClassMetadata($subClassName);
$this->_gatherColumns($subClass, $table);
$this->_gatherRelationsSql($subClass, $table, $schema);
$this->gatherColumns($subClass, $table);
$this->gatherRelationsSql($subClass, $table, $schema);
$processedClasses[$subClassName] = true;
}
} else if ($class->isInheritanceTypeJoined()) {
} elseif ($class->isInheritanceTypeJoined()) {
// Add all non-inherited fields as columns
$pkColumns = array();
foreach ($class->fieldMappings as $fieldName => $mapping) {
if ( ! isset($mapping['inherited'])) {
$columnName = $this->quoteStrategy->getColumnName($mapping['fieldName'], $class, $this->platform);
$this->_gatherColumn($class, $mapping, $table);
$this->gatherColumn($class, $mapping, $table);
if ($class->isIdentifier($fieldName)) {
$pkColumns[] = $columnName;
@ -181,7 +182,7 @@ class SchemaTool
}
}
$this->_gatherRelationsSql($class, $table, $schema);
$this->gatherRelationsSql($class, $table, $schema);
// Add the discriminator column only to the root table
if ($class->name == $class->rootEntityName) {
@ -190,7 +191,7 @@ class SchemaTool
// Add an ID FK column to child tables
/* @var \Doctrine\ORM\Mapping\ClassMetadata $class */
$idMapping = $class->fieldMappings[$class->identifier[0]];
$this->_gatherColumn($class, $idMapping, $table);
$this->gatherColumn($class, $idMapping, $table);
$columnName = $this->quoteStrategy->getColumnName($class->identifier[0], $class, $this->platform);
// TODO: This seems rather hackish, can we optimize it?
$table->getColumn($columnName)->setAutoincrement(false);
@ -198,7 +199,7 @@ class SchemaTool
$pkColumns[] = $columnName;
// Add a FK constraint on the ID column
$table->addUnnamedForeignKeyConstraint(
$table->addForeignKeyConstraint(
$this->quoteStrategy->getTableName($this->em->getClassMetadata($class->rootEntityName), $this->platform),
array($columnName), array($columnName), array('onDelete' => 'CASCADE')
);
@ -206,18 +207,18 @@ class SchemaTool
$table->setPrimaryKey($pkColumns);
} else if ($class->isInheritanceTypeTablePerClass()) {
} elseif ($class->isInheritanceTypeTablePerClass()) {
throw ORMException::notSupported();
} else {
$this->_gatherColumns($class, $table);
$this->_gatherRelationsSql($class, $table, $schema);
$this->gatherColumns($class, $table);
$this->gatherRelationsSql($class, $table, $schema);
}
$pkColumns = array();
foreach ($class->identifier as $identifierField) {
if (isset($class->fieldMappings[$identifierField])) {
$pkColumns[] = $this->quoteStrategy->getColumnName($identifierField, $class, $this->platform);
} else if (isset($class->associationMappings[$identifierField])) {
} elseif (isset($class->associationMappings[$identifierField])) {
/* @var $assoc \Doctrine\ORM\Mapping\OneToOne */
$assoc = $class->associationMappings[$identifierField];
foreach ($assoc['joinColumns'] as $joinColumn) {
@ -283,10 +284,11 @@ class SchemaTool
* column of a class.
*
* @param ClassMetadata $class
* @param Table $table
* @return array The portable column definition of the discriminator column as required by
* the DBAL.
*/
private function addDiscriminatorColumnDefinition($class, $table)
private function addDiscriminatorColumnDefinition($class, Table $table)
{
$discrColumn = $class->discriminatorColumn;
@ -315,17 +317,16 @@ class SchemaTool
* @param Table $table
* @return array The list of portable column definitions as required by the DBAL.
*/
private function _gatherColumns($class, $table)
private function gatherColumns($class, Table $table)
{
$columns = array();
$pkColumns = array();
foreach ($class->fieldMappings as $fieldName => $mapping) {
foreach ($class->fieldMappings as $mapping) {
if ($class->isInheritanceTypeSingleTable() && isset($mapping['inherited'])) {
continue;
}
$column = $this->_gatherColumn($class, $mapping, $table);
$this->gatherColumn($class, $mapping, $table);
if ($class->isIdentifier($mapping['fieldName'])) {
$pkColumns[] = $this->quoteStrategy->getColumnName($mapping['fieldName'], $class, $this->platform);
@ -337,8 +338,6 @@ class SchemaTool
if(!$table->hasIndex('primary')) {
//$table->setPrimaryKey($pkColumns);
}
return $columns;
}
/**
@ -349,7 +348,7 @@ class SchemaTool
* @param Table $table
* @return array The portable column definition as required by the DBAL.
*/
private function _gatherColumn($class, array $mapping, $table)
private function gatherColumn($class, array $mapping, Table $table)
{
$columnName = $this->quoteStrategy->getColumnName($mapping['fieldName'], $class, $this->platform);
$columnType = $mapping['type'];
@ -423,9 +422,9 @@ class SchemaTool
* @param \Doctrine\DBAL\Schema\Schema $schema
* @return void
*/
private function _gatherRelationsSql($class, $table, $schema)
private function gatherRelationsSql($class, Table $table, $schema)
{
foreach ($class->associationMappings as $fieldName => $mapping) {
foreach ($class->associationMappings as $mapping) {
if (isset($mapping['inherited'])) {
continue;
}
@ -440,10 +439,10 @@ class SchemaTool
foreach($uniqueConstraints as $indexName => $unique) {
$table->addUniqueIndex($unique['columns'], is_numeric($indexName) ? null : $indexName);
}
} else if ($mapping['type'] == ClassMetadata::ONE_TO_MANY && $mapping['isOwningSide']) {
} elseif ($mapping['type'] == ClassMetadata::ONE_TO_MANY && $mapping['isOwningSide']) {
//... create join table, one-many through join table supported later
throw ORMException::notSupported();
} else if ($mapping['type'] == ClassMetadata::MANY_TO_MANY && $mapping['isOwningSide']) {
} elseif ($mapping['type'] == ClassMetadata::MANY_TO_MANY && $mapping['isOwningSide']) {
// create join table
$joinTable = $mapping['joinTable'];
@ -485,7 +484,9 @@ class SchemaTool
if ($class->hasField($referencedFieldName)) {
return array($class, $referencedFieldName);
} else if (in_array($referencedColumnName, $class->getIdentifierColumnNames())) {
}
if (in_array($referencedColumnName, $class->getIdentifierColumnNames())) {
// it seems to be an entity as foreign key
foreach ($class->getIdentifierFieldNames() as $fieldName) {
if ($class->hasAssociation($fieldName) && $class->getSingleAssociationJoinColumnName($fieldName) == $referencedColumnName) {
@ -545,16 +546,19 @@ class SchemaTool
$columnDef = null;
if (isset($joinColumn['columnDefinition'])) {
$columnDef = $joinColumn['columnDefinition'];
} else if (isset($fieldMapping['columnDefinition'])) {
} elseif (isset($fieldMapping['columnDefinition'])) {
$columnDef = $fieldMapping['columnDefinition'];
}
$columnOptions = array('notnull' => false, 'columnDefinition' => $columnDef);
if (isset($joinColumn['nullable'])) {
$columnOptions['notnull'] = !$joinColumn['nullable'];
}
if ($fieldMapping['type'] == "string" && isset($fieldMapping['length'])) {
$columnOptions['length'] = $fieldMapping['length'];
} else if ($fieldMapping['type'] == "decimal") {
} elseif ($fieldMapping['type'] == "decimal") {
$columnOptions['scale'] = $fieldMapping['scale'];
$columnOptions['precision'] = $fieldMapping['precision'];
}
@ -571,7 +575,7 @@ class SchemaTool
}
}
$theJoinTable->addUnnamedForeignKeyConstraint(
$theJoinTable->addForeignKeyConstraint(
$foreignTableName, $localColumns, $foreignColumns, $fkOptions
);
}
@ -593,7 +597,7 @@ class SchemaTool
foreach ($dropSchemaSql as $sql) {
try {
$conn->executeQuery($sql);
} catch(\Exception $e) {
} catch (\Exception $e) {
}
}
@ -624,9 +628,9 @@ class SchemaTool
$sm = $this->em->getConnection()->getSchemaManager();
$schema = $sm->createSchema();
$visitor = new \Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector($this->platform);
/* @var $schema \Doctrine\DBAL\Schema\Schema */
$visitor = new DropSchemaSqlCollector($this->platform);
$schema->visit($visitor);
return $visitor->getQueries();
}
@ -638,11 +642,12 @@ class SchemaTool
*/
public function getDropSchemaSQL(array $classes)
{
$visitor = new \Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector($this->platform);
$visitor = new DropSchemaSqlCollector($this->platform);
$schema = $this->getSchemaFromMetadata($classes);
$sm = $this->em->getConnection()->getSchemaManager();
$fullSchema = $sm->createSchema();
foreach ($fullSchema->getTables() as $table) {
if ( ! $schema->hasTable($table->getName())) {
foreach ($table->getForeignKeys() as $foreignKey) {
@ -663,6 +668,7 @@ class SchemaTool
foreach ($schema->getSequences() as $sequence) {
$visitor->acceptSequence($sequence);
}
foreach ($schema->getTables() as $table) {
/* @var $sequence Table */
if ($table->hasPrimaryKey()) {
@ -689,7 +695,7 @@ class SchemaTool
* @param boolean $saveMode
* @return void
*/
public function updateSchema(array $classes, $saveMode=false)
public function updateSchema(array $classes, $saveMode = false)
{
$updateSchemaSql = $this->getUpdateSchemaSql($classes, $saveMode);
$conn = $this->em->getConnection();
@ -709,20 +715,20 @@ class SchemaTool
* @param boolean $saveMode True for writing to DB, false for SQL string
* @return array The sequence of SQL statements.
*/
public function getUpdateSchemaSql(array $classes, $saveMode=false)
public function getUpdateSchemaSql(array $classes, $saveMode = false)
{
$sm = $this->em->getConnection()->getSchemaManager();
$fromSchema = $sm->createSchema();
$toSchema = $this->getSchemaFromMetadata($classes);
$comparator = new \Doctrine\DBAL\Schema\Comparator();
$comparator = new Comparator();
$schemaDiff = $comparator->compare($fromSchema, $toSchema);
if ($saveMode) {
return $schemaDiff->toSaveSql($this->platform);
} else {
return $schemaDiff->toSql($this->platform);
}
return $schemaDiff->toSql($this->platform);
}
}

View File

@ -111,7 +111,6 @@ class SchemaValidator
"the target entity '". $targetMetadata->name . "' also maps an association as identifier.";
}
/* @var $assoc AssociationMapping */
if ($assoc['mappedBy']) {
if ($targetMetadata->hasField($assoc['mappedBy'])) {
$ce[] = "The association " . $class->name . "#" . $fieldName . " refers to the owning side ".
@ -120,12 +119,12 @@ class SchemaValidator
if (!$targetMetadata->hasAssociation($assoc['mappedBy'])) {
$ce[] = "The association " . $class->name . "#" . $fieldName . " refers to the owning side ".
"field " . $assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " which does not exist.";
} else if ($targetMetadata->associationMappings[$assoc['mappedBy']]['inversedBy'] == null) {
} elseif ($targetMetadata->associationMappings[$assoc['mappedBy']]['inversedBy'] == null) {
$ce[] = "The field " . $class->name . "#" . $fieldName . " is on the inverse side of a ".
"bi-directional relationship, but the specified mappedBy association on the target-entity ".
$assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " does not contain the required ".
"'inversedBy=".$fieldName."' attribute.";
} else if ($targetMetadata->associationMappings[$assoc['mappedBy']]['inversedBy'] != $fieldName) {
} elseif ($targetMetadata->associationMappings[$assoc['mappedBy']]['inversedBy'] != $fieldName) {
$ce[] = "The mappings " . $class->name . "#" . $fieldName . " and " .
$assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " are ".
"inconsistent with each other.";
@ -137,15 +136,16 @@ class SchemaValidator
$ce[] = "The association " . $class->name . "#" . $fieldName . " refers to the inverse side ".
"field " . $assoc['targetEntity'] . "#" . $assoc['inversedBy'] . " which is not defined as association.";
}
if (!$targetMetadata->hasAssociation($assoc['inversedBy'])) {
$ce[] = "The association " . $class->name . "#" . $fieldName . " refers to the inverse side ".
"field " . $assoc['targetEntity'] . "#" . $assoc['inversedBy'] . " which does not exist.";
} else if ($targetMetadata->associationMappings[$assoc['inversedBy']]['mappedBy'] == null) {
} elseif ($targetMetadata->associationMappings[$assoc['inversedBy']]['mappedBy'] == null) {
$ce[] = "The field " . $class->name . "#" . $fieldName . " is on the owning side of a ".
"bi-directional relationship, but the specified mappedBy association on the target-entity ".
$assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " does not contain the required ".
"'inversedBy' attribute.";
} else if ($targetMetadata->associationMappings[$assoc['inversedBy']]['mappedBy'] != $fieldName) {
} elseif ($targetMetadata->associationMappings[$assoc['inversedBy']]['mappedBy'] != $fieldName) {
$ce[] = "The mappings " . $class->name . "#" . $fieldName . " and " .
$assoc['targetEntity'] . "#" . $assoc['inversedBy'] . " are ".
"inconsistent with each other.";
@ -157,10 +157,10 @@ class SchemaValidator
if ($assoc['type'] == ClassMetadataInfo::ONE_TO_ONE && $targetAssoc['type'] !== ClassMetadataInfo::ONE_TO_ONE){
$ce[] = "If association " . $class->name . "#" . $fieldName . " is one-to-one, then the inversed " .
"side " . $targetMetadata->name . "#" . $assoc['inversedBy'] . " has to be one-to-one as well.";
} else if ($assoc['type'] == ClassMetadataInfo::MANY_TO_ONE && $targetAssoc['type'] !== ClassMetadataInfo::ONE_TO_MANY){
} elseif ($assoc['type'] == ClassMetadataInfo::MANY_TO_ONE && $targetAssoc['type'] !== ClassMetadataInfo::ONE_TO_MANY){
$ce[] = "If association " . $class->name . "#" . $fieldName . " is many-to-one, then the inversed " .
"side " . $targetMetadata->name . "#" . $assoc['inversedBy'] . " has to be one-to-many.";
} else if ($assoc['type'] == ClassMetadataInfo::MANY_TO_MANY && $targetAssoc['type'] !== ClassMetadataInfo::MANY_TO_MANY){
} elseif ($assoc['type'] == ClassMetadataInfo::MANY_TO_MANY && $targetAssoc['type'] !== ClassMetadataInfo::MANY_TO_MANY){
$ce[] = "If association " . $class->name . "#" . $fieldName . " is many-to-many, then the inversed " .
"side " . $targetMetadata->name . "#" . $assoc['inversedBy'] . " has to be many-to-many as well.";
}
@ -201,7 +201,7 @@ class SchemaValidator
"' are missing.";
}
} else if ($assoc['type'] & ClassMetadataInfo::TO_ONE) {
} elseif ($assoc['type'] & ClassMetadataInfo::TO_ONE) {
$identifierColumns = $targetMetadata->getIdentifierColumnNames();
foreach ($assoc['joinColumns'] as $joinColumn) {
if (!in_array($joinColumn['referencedColumnName'], $identifierColumns)) {
@ -212,6 +212,7 @@ class SchemaValidator
if (count($identifierColumns) != count($assoc['joinColumns'])) {
$ids = array();
foreach ($assoc['joinColumns'] as $joinColumn) {
$ids[] = $joinColumn['name'];
}
@ -238,6 +239,7 @@ class SchemaValidator
if ($publicAttr->isStatic()) {
continue;
}
$ce[] = "Field '".$publicAttr->getName()."' in class '".$class->name."' must be private ".
"or protected. Public fields may break lazy-loading.";
}
@ -252,28 +254,6 @@ class SchemaValidator
return $ce;
}
/**
* @param string $columnName
* @param ClassMetadataInfo $class
* @return bool
*/
private function columnExistsOnEntity($columnName, $class)
{
if (isset($class->fieldNames[$columnName])) {
return true;
}
foreach ($class->associationMappings as $assoc) {
if ($assoc['isOwningSide']) {
foreach ($assoc['joinColumns'] as $columnMapping) {
if ($columnMapping['name'] == $columnName) {
return true;
}
}
}
}
return false;
}
/**
* Check if the Database Schema is in sync with the current metadata state.
*
@ -284,6 +264,7 @@ class SchemaValidator
$schemaTool = new SchemaTool($this->em);
$allMetadata = $this->em->getMetadataFactory()->getAllMetadata();
return (count($schemaTool->getUpdateSchemaSql($allMetadata, true)) == 0);
return count($schemaTool->getUpdateSchemaSql($allMetadata, true)) == 0;
}
}

View File

@ -40,7 +40,7 @@ class Setup
* @param string $gitCheckoutRootPath
* @return void
*/
static public function registerAutoloadGit($gitCheckoutRootPath)
public static function registerAutoloadGit($gitCheckoutRootPath)
{
if (!class_exists('Doctrine\Common\ClassLoader', false)) {
require_once $gitCheckoutRootPath . "/lib/vendor/doctrine-common/lib/Doctrine/Common/ClassLoader.php";
@ -65,7 +65,7 @@ class Setup
*
* @return void
*/
static public function registerAutoloadPEAR()
public static function registerAutoloadPEAR()
{
if (!class_exists('Doctrine\Common\ClassLoader', false)) {
require_once "Doctrine/Common/ClassLoader.php";
@ -91,7 +91,7 @@ class Setup
*
* @param string $directory
*/
static public function registerAutoloadDirectory($directory)
public static function registerAutoloadDirectory($directory)
{
if (!class_exists('Doctrine\Common\ClassLoader', false)) {
require_once $directory . "/Doctrine/Common/ClassLoader.php";
@ -114,10 +114,11 @@ class Setup
* @param bool $useSimpleAnnotationReader
* @return Configuration
*/
static public function createAnnotationMetadataConfiguration(array $paths, $isDevMode = false, $proxyDir = null, Cache $cache = null, $useSimpleAnnotationReader = true)
public static function createAnnotationMetadataConfiguration(array $paths, $isDevMode = false, $proxyDir = null, Cache $cache = null, $useSimpleAnnotationReader = true)
{
$config = self::createConfiguration($isDevMode, $proxyDir, $cache);
$config->setMetadataDriverImpl($config->newDefaultAnnotationDriver($paths, $useSimpleAnnotationReader));
return $config;
}
@ -130,10 +131,11 @@ class Setup
* @param Cache $cache
* @return Configuration
*/
static public function createXMLMetadataConfiguration(array $paths, $isDevMode = false, $proxyDir = null, Cache $cache = null)
public static function createXMLMetadataConfiguration(array $paths, $isDevMode = false, $proxyDir = null, Cache $cache = null)
{
$config = self::createConfiguration($isDevMode, $proxyDir, $cache);
$config->setMetadataDriverImpl(new XmlDriver($paths));
return $config;
}
@ -146,10 +148,11 @@ class Setup
* @param Cache $cache
* @return Configuration
*/
static public function createYAMLMetadataConfiguration(array $paths, $isDevMode = false, $proxyDir = null, Cache $cache = null)
public static function createYAMLMetadataConfiguration(array $paths, $isDevMode = false, $proxyDir = null, Cache $cache = null)
{
$config = self::createConfiguration($isDevMode, $proxyDir, $cache);
$config->setMetadataDriverImpl(new YamlDriver($paths));
return $config;
}
@ -161,20 +164,21 @@ class Setup
* @param Cache $cache
* @return Configuration
*/
static public function createConfiguration($isDevMode = false, $proxyDir = null, Cache $cache = null)
public static function createConfiguration($isDevMode = false, $proxyDir = null, Cache $cache = null)
{
$proxyDir = $proxyDir ?: sys_get_temp_dir();
if ($isDevMode === false && $cache === null) {
if (extension_loaded('apc')) {
$cache = new \Doctrine\Common\Cache\ApcCache();
} else if (extension_loaded('xcache')) {
} elseif (extension_loaded('xcache')) {
$cache = new \Doctrine\Common\Cache\XcacheCache();
} else if (extension_loaded('memcache')) {
} elseif (extension_loaded('memcache')) {
$memcache = new \Memcache();
$memcache->connect('127.0.0.1');
$cache = new \Doctrine\Common\Cache\MemcacheCache();
$cache->setMemcache($memcache);
} else if (extension_loaded('redis')) {
} elseif (extension_loaded('redis')) {
$redis = new \Redis();
$redis->connect('127.0.0.1');
$cache = new \Doctrine\Common\Cache\RedisCache();
@ -182,9 +186,10 @@ class Setup
} else {
$cache = new ArrayCache();
}
} else if ($cache === null) {
} elseif ($cache === null) {
$cache = new ArrayCache();
}
$cache->setNamespace("dc2_" . md5($proxyDir) . "_"); // to avoid collisions
$config = new Configuration();

View File

@ -230,9 +230,9 @@ class ConfigurationTest extends PHPUnit_Framework_TestCase
public function testAddGetFilters()
{
$this->assertSame(null, $this->configuration->getFilterClassName('NonExistingFilter'));
$this->assertSame(null, $this->configuration->getFilter('NonExistingFilter'));
$this->configuration->addFilter('FilterName', __CLASS__);
$this->assertSame(__CLASS__, $this->configuration->getFilterClassName('FilterName'));
$this->assertSame(__CLASS__, $this->configuration->getFilter('FilterName'));
}
public function setDefaultRepositoryClassName()

View File

@ -58,11 +58,27 @@ class SQLFilterTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function testConfigureFilter()
{
$config = new \Doctrine\ORM\Configuration();
$validFilter = $this->getMockBuilder('\Doctrine\ORM\Query\Filter\SQLFilter')
->disableOriginalConstructor()
->getMock();
$config->addFilter("geolocation", $validFilter);
$config->addFilter("locale", "\Doctrine\Tests\ORM\Functional\MyLocaleFilter");
$this->assertEquals("\Doctrine\Tests\ORM\Functional\MyLocaleFilter", $config->getFilterClassName("locale"));
$this->assertNull($config->getFilterClassName("foo"));
$this->assertEquals("\Doctrine\Tests\ORM\Functional\MyLocaleFilter", $config->getFilter("locale"));
$this->assertNull($config->getFilter("foo"));
$this->assertInstanceOf("\Doctrine\ORM\Query\Filter\SQLFilter", $config->getFilter("geolocation"));
}
/**
* @expectedException InvalidArgumentException
*/
public function testConfigureFilterFails()
{
$config = new \Doctrine\ORM\Configuration();
$invalidFilter = $this->getMock('\StdClass');
$config->addFilter("geolocation", $invalidFilter);
}
public function testEntityManagerEnableFilter()
@ -453,6 +469,22 @@ class SQLFilterTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals(1, count($query->getResult()));
}
public function testWhereOrFilter()
{
$this->loadFixtureData();
$query = $this->_em->createQuery('select ug from Doctrine\Tests\Models\CMS\CmsGroup ug WHERE 1=1 OR 1=1');
// We get two users before enabling the filter
$this->assertEquals(2, count($query->getResult()));
$conf = $this->_em->getConfiguration();
$conf->addFilter("group_prefix", "\Doctrine\Tests\ORM\Functional\CMSGroupPrefixFilter");
$this->_em->getFilters()->enable("group_prefix")->setParameter("prefix", "bar_%", DBALType::STRING);
// We get one user after enabling the filter
$this->assertEquals(1, count($query->getResult()));
}
private function loadLazyFixtureData()
{

View File

@ -100,6 +100,11 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
$this->assertValidDQL('SELECT COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u');
}
public function testMultipleParenthesisInSelect()
{
$this->assertValidDQL('SELECT (((u.id))) as v FROM Doctrine\Tests\Models\CMS\CmsUser u');
}
public function testDuplicatedAliasInAggregateFunction()
{
$this->assertInvalidDQL('SELECT COUNT(u.id) AS num, SUM(u.id) AS num FROM Doctrine\Tests\Models\CMS\CmsUser u');

View File

@ -9,15 +9,14 @@ class ConvertDoctrine1SchemaCommandTest extends \Doctrine\Tests\OrmTestCase
public function testExecution()
{
$entityGenerator = $this->getMock('Doctrine\ORM\Tools\EntityGenerator');
$metadataExporter = $this->getMock('Doctrine\ORM\Tools\Export\ClassMetadataExporter');
$command = new ConvertDoctrine1SchemaCommand();
$command->setEntityGenerator($entityGenerator);
$output = $this->getMock('Symfony\Component\Console\Output\OutputInterface');
$output->expects($this->once())
->method('write')
->with($this->equalTo('No Metadata Classes to process.' . PHP_EOL));
->method('writeln')
->with($this->equalTo('No Metadata Classes to process.'));
$command->convertDoctrine1Schema($this->_getTestEntityManager(), array(), sys_get_temp_dir(), 'annotation', 4, null, $output);
$command->convertDoctrine1Schema(array(), sys_get_temp_dir(), 'annotation', 4, null, $output);
}
}
}