1
0
mirror of synced 2025-01-18 22:41:43 +03:00

Merge commit 'upstream/master'

This commit is contained in:
Roman S. Borschel 2010-04-13 00:50:12 +02:00
commit 6d08164162
23 changed files with 396 additions and 364 deletions

View File

@ -1,6 +1,62 @@
# Upgrade from 2.0-ALPHA4 to 2.0-BETA1
## Console migrated to Symfony Console
The Doctrine Cli has been replaced by Symfony Console Configuration
Instead of having to specifiy:
[php]
$cliConfig = new CliConfiguration();
$cliConfig->setAttribute('em', $entityManager);
You now have to configure the script like:
[php]
$helperSet = new \Symfony\Components\Console\Helper\HelperSet(array(
'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
));
## Console: No need for Mapping Paths anymore
In previous versions you had to specify the --from and --from-path options
to show where your mapping paths are from the console. However this information
is already known from the Mapping Driver configuration, so the requirement
for this options were dropped.
Instead for each console command all the entities are loaded and to
restrict the operation to one or more sub-groups you can use the --filter flag.
## AnnotationDriver is not a default mapping driver anymore
In conjunction with the recent changes to Console we realized that the
annotations driver being a default metadata driver lead to lots of glue
code in the console components to detect where entities lie and how to load
them for batch updates like SchemaTool and other commands. However the
annotations driver being a default driver does not really help that much
anyways.
Therefore we decided to break backwards compability in this issue and drop
the support for Annotations as Default Driver and require our users to
specify the driver explicitly (which allows us to ask for the path to all
entities).
If you are using the annotations metadata driver as default driver, you
have to add the following lines to your bootstrap code:
$driverImpl = $config->newDefaultAnnotationDriver(array(__DIR__."/Entities"));
$config->setMetadataDriverImpl($driverImpl);
You have to specify the path to your entities as either string of a single
path or array of multiple paths
to your entities. This information will be used by all console commands to
access all entities.
Xml and Yaml Drivers work as before!
## New inversedBy attribute
It is now *mandatory* that the owning side of a bidirectional association specifies the

View File

@ -19,6 +19,9 @@
namespace Doctrine\ORM;
use Doctrine\Common\Cache\Cache,
Doctrine\ORM\Mapping\Driver\Driver;
/**
* Configuration container for all configuration options of Doctrine.
* It combines all configuration options from DBAL & ORM.
@ -116,15 +119,29 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Sets the cache driver implementation that is used for metadata caching.
*
* @param object $driverImpl
* @param Driver $driverImpl
* @todo Force parameter to be a Closure to ensure lazy evaluation
* (as soon as a metadata cache is in effect, the driver never needs to initialize).
*/
public function setMetadataDriverImpl($driverImpl)
public function setMetadataDriverImpl(Driver $driverImpl)
{
$this->_attributes['metadataDriverImpl'] = $driverImpl;
}
/**
* Add a new default annotation driver with a correctly configured annotation reader.
*
* @param array $paths
* @return Mapping\Driver\AnnotationDriver
*/
public function newDefaultAnnotationDriver($paths = array())
{
$reader = new \Doctrine\Common\Annotations\AnnotationReader();
$reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
return new \Doctrine\ORM\Mapping\Driver\AnnotationDriver($reader, (array)$paths);
}
/**
* Adds a namespace under a certain alias.
*
@ -166,23 +183,18 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Gets the cache driver implementation that is used for the mapping metadata.
*
* @return object
* @throws ORMException
* @return Mapping\Driver\Driver
*/
public function getMetadataDriverImpl()
{
if ($this->_attributes['metadataDriverImpl'] == null) {
$reader = new \Doctrine\Common\Annotations\AnnotationReader(new \Doctrine\Common\Cache\ArrayCache);
$reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
$this->_attributes['metadataDriverImpl'] = new \Doctrine\ORM\Mapping\Driver\AnnotationDriver($reader);
}
return $this->_attributes['metadataDriverImpl'];
}
/**
* Gets the cache driver implementation that is used for query result caching.
*
* @return object
* @return \Doctrine\Common\Cache\Cache
*/
public function getResultCacheImpl()
{
@ -192,9 +204,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Sets the cache driver implementation that is used for query result caching.
*
* @param object $cacheImpl
* @param \Doctrine\Common\Cache\Cache $cacheImpl
*/
public function setResultCacheImpl($cacheImpl)
public function setResultCacheImpl(Cache $cacheImpl)
{
$this->_attributes['resultCacheImpl'] = $cacheImpl;
}
@ -202,7 +214,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Gets the cache driver implementation that is used for the query cache (SQL cache).
*
* @return object
* @return \Doctrine\Common\Cache\Cache
*/
public function getQueryCacheImpl()
{
@ -212,9 +224,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Sets the cache driver implementation that is used for the query cache (SQL cache).
*
* @param object $cacheImpl
* @param \Doctrine\Common\Cache\Cache $cacheImpl
*/
public function setQueryCacheImpl($cacheImpl)
public function setQueryCacheImpl(Cache $cacheImpl)
{
$this->_attributes['queryCacheImpl'] = $cacheImpl;
}
@ -222,7 +234,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Gets the cache driver implementation that is used for metadata caching.
*
* @return object
* @return \Doctrine\Common\Cache\Cache
*/
public function getMetadataCacheImpl()
{
@ -232,9 +244,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Sets the cache driver implementation that is used for metadata caching.
*
* @param object $cacheImpl
* @param \Doctrine\Common\Cache\Cache $cacheImpl
*/
public function setMetadataCacheImpl($cacheImpl)
public function setMetadataCacheImpl(Cache $cacheImpl)
{
$this->_attributes['metadataCacheImpl'] = $cacheImpl;
}

View File

@ -593,9 +593,11 @@ class EntityManager
* @param EventManager $eventManager The EventManager instance to use.
* @return EntityManager The created EntityManager.
*/
public static function create($conn, Configuration $config = null, EventManager $eventManager = null)
public static function create($conn, Configuration $config, EventManager $eventManager = null)
{
$config = $config ?: new Configuration();
if (!$config->getMetadataDriverImpl()) {
throw ORMException::missingMappingDriverImpl();
}
if (is_array($conn)) {
$conn = \Doctrine\DBAL\DriverManager::getConnection($conn, $config, ($eventManager ?: new EventManager()));

View File

@ -428,40 +428,41 @@ class AnnotationDriver implements Driver
return $this->_classNames;
}
if (!$this->_paths) {
throw MappingException::pathRequired();
}
$classes = array();
$includedFiles = array();
if ($this->_paths) {
$includedFiles = array();
foreach ((array) $this->_paths as $path) {
if ( ! is_dir($path)) {
throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath();
}
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($path),
\RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($iterator as $file) {
if (($fileName = $file->getBasename($this->_fileExtension)) == $file->getBasename()) {
continue;
}
$sourceFile = realpath($file->getPathName());
require_once $sourceFile;
$includedFiles[] = $sourceFile;
}
foreach ($this->_paths as $path) {
if ( ! is_dir($path)) {
throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath();
}
$declared = get_declared_classes();
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($path),
\RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($declared as $className) {
$rc = new \ReflectionClass($className);
$sourceFile = $rc->getFileName();
if (in_array($sourceFile, $includedFiles) && ! $this->isTransient($className)) {
$classes[] = $className;
foreach ($iterator as $file) {
if (($fileName = $file->getBasename($this->_fileExtension)) == $file->getBasename()) {
continue;
}
$sourceFile = realpath($file->getPathName());
require_once $sourceFile;
$includedFiles[] = $sourceFile;
}
}
$declared = get_declared_classes();
foreach ($declared as $className) {
$rc = new \ReflectionClass($className);
$sourceFile = $rc->getFileName();
if (in_array($sourceFile, $includedFiles) && ! $this->isTransient($className)) {
$classes[] = $className;
}
}
@ -470,4 +471,19 @@ class AnnotationDriver implements Driver
return $classes;
}
/**
* Factory method for the Annotation Driver
*
* @param array|string $paths
* @param AnnotationReader $reader
* @return AnnotationDriver
*/
static public function create($paths = array(), AnnotationReader $reader = null)
{
if ($reader == null) {
$reader = new AnnotationReader();
$reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
}
return new self($reader, $paths);
}
}

View File

@ -28,6 +28,12 @@ namespace Doctrine\ORM\Mapping;
*/
class MappingException extends \Doctrine\ORM\ORMException
{
public static function pathRequired()
{
return new self("Specifying the paths to your entities is required ".
"in the AnnotationDriver to retrieve all class names.");
}
public static function identifierRequired($entityName)
{
return new self("No identifier/primary key specified for Entity '$entityName'."

View File

@ -10,6 +10,12 @@ namespace Doctrine\ORM;
*/
class ORMException extends \Exception
{
public static function missingMappingDriverImpl()
{
return new self("It's a requirement to specify a Metadata Driver and pass it ".
"to Doctrine\ORM\Configuration::setMetadataDriverImpl().");
}
public static function entityMissingAssignedId($entity)
{
return new self("Entity of type " . get_class($entity) . " is missing an assigned ID.");

View File

@ -23,7 +23,9 @@ namespace Doctrine\ORM\Tools\Console\Command;
use Symfony\Components\Console\Input\InputArgument,
Symfony\Components\Console\Input\InputOption,
Symfony\Components\Console;
Symfony\Components\Console,
Doctrine\ORM\Tools\Export\ClassMetadataExporter,
Doctrine\ORM\Tools\ConvertDoctrine1Schema;
/**
* Command to convert a Doctrine 1 schema to a Doctrine 2 mapping file.

View File

@ -23,7 +23,9 @@ namespace Doctrine\ORM\Tools\Console\Command;
use Symfony\Components\Console\Input\InputArgument,
Symfony\Components\Console\Input\InputOption,
Symfony\Components\Console;
Symfony\Components\Console,
Doctrine\ORM\Tools\Console\MetadataFilter,
Doctrine\ORM\Tools\Export\ClassMetadataExporter;
/**
* Command to convert your mapping information between the various formats.
@ -48,8 +50,9 @@ class ConvertMappingCommand extends Console\Command\Command
->setName('orm:convert-mapping')
->setDescription('Convert mapping information between supported formats.')
->setDefinition(array(
new InputArgument(
'from-path', InputArgument::REQUIRED, 'The path of mapping information.'
new InputOption(
'filter', null, InputOption::PARAMETER_REQUIRED | InputOption::PARAMETER_IS_ARRAY,
'A string pattern used to match entities that should be processed.'
),
new InputArgument(
'to-type', InputArgument::REQUIRED, 'The mapping type to be converted.'
@ -58,10 +61,8 @@ class ConvertMappingCommand extends Console\Command\Command
'dest-path', InputArgument::REQUIRED,
'The path to generate your entities classes.'
),
new InputOption(
'from', null, InputOption::PARAMETER_REQUIRED | InputOption::PARAMETER_IS_ARRAY,
'Optional paths of mapping information.',
array()
new InputArgument(
'from-database', InputArgument::OPTIONAL, 'The path of mapping information.'
),
new InputOption(
'extend', null, InputOption::PARAMETER_OPTIONAL,
@ -84,37 +85,16 @@ EOT
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
{
$em = $this->getHelper('em')->getEntityManager();
$cme = new ClassMetadataExporter();
// Process source directories
$fromPath = $input->getArgument('from-path');
$metadatas = $em->getMetadataFactory()->getAllMetadata();
$metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter'));
if (strtolower($fromPath) !== 'database') {
$fromPaths = array_merge(array($fromPath), $input->getOption('from'));
foreach ($fromPaths as &$dirName) {
$dirName = realpath($dirName);
if ( ! file_exists($dirName)) {
throw new \InvalidArgumentException(
sprintf("Mapping directory '<info>%s</info>' does not exist.", $dirName)
);
} else if ( ! is_readable($dirName)) {
throw new \InvalidArgumentException(
sprintf("Mapping directory '<info>%s</info>' does not have read permissions.", $dirName)
);
}
$cme->addMappingSource($dirName);
}
} else {
if ($input->getArgument('from-database') === true) {
$em->getConfiguration()->setMetadataDriverImpl(
new \Doctrine\ORM\Mapping\Driver\DatabaseDriver(
$em->getConnection()->getSchemaManager()
)
);
$cme->addMappingSource($fromPath);
}
// Process destination directory
@ -132,6 +112,7 @@ EOT
$toType = strtolower($input->getArgument('to-type'));
$cme = new ClassMetadataExporter();
$exporter = $cme->getExporter($toType, $destPath);
if ($toType == 'annotation') {
@ -145,9 +126,7 @@ EOT
}
}
$metadatas = $cme->getMetadatas();
if ($metadatas) {
if (count($metadatas)) {
foreach ($metadatas as $metadata) {
$output->write(sprintf('Processing entity "<info>%s</info>"', $metadata->name) . PHP_EOL);
}
@ -156,7 +135,7 @@ EOT
$exporter->export();
$output->write(PHP_EOL . sprintf(
'Exporting "<info>%s</info>" mapping information to "<info>%s</info>"', $toType, $destPath
'Exporting "<info>%s</info>" mapping information to "<info>%s</info>"' . PHP_EOL, $toType, $destPath
));
} else {
$output->write('No Metadata Classes to process.' . PHP_EOL);

View File

@ -23,7 +23,9 @@ namespace Doctrine\ORM\Tools\Console\Command;
use Symfony\Components\Console\Input\InputArgument,
Symfony\Components\Console\Input\InputOption,
Symfony\Components\Console;
Symfony\Components\Console,
Doctrine\ORM\Tools\Console\MetadataFilter,
Doctrine\ORM\Tools\EntityGenerator;
/**
* Command to generate entity classes and method stubs from your mapping information.
@ -48,17 +50,13 @@ class GenerateEntitiesCommand extends Console\Command\Command
->setName('orm:generate-entities')
->setDescription('Generate entity classes and method stubs from your mapping information.')
->setDefinition(array(
new InputArgument(
'from-path', InputArgument::REQUIRED, 'The path of mapping information.'
new InputOption(
'filter', null, InputOption::PARAMETER_REQUIRED | InputOption::PARAMETER_IS_ARRAY,
'A string pattern used to match entities that should be processed.'
),
new InputArgument(
'dest-path', InputArgument::REQUIRED, 'The path to generate your entity classes.'
),
new InputOption(
'from', null, InputOption::PARAMETER_REQUIRED | InputOption::PARAMETER_IS_ARRAY,
'Optional paths of mapping information.',
array()
),
new InputOption(
'generate-annotations', null, InputOption::PARAMETER_OPTIONAL,
'Flag to define if generator should generate annotation metadata on entities.', false
@ -96,29 +94,10 @@ EOT
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
{
$em = $this->getHelper('em')->getEntityManager();
$reader = new ClassMetadataReader();
$reader->setEntityManager($em);
// Process source directories
$fromPaths = array_merge(array($input->getArgument('from-path')), $input->getOption('from'));
foreach ($fromPaths as $dirName) {
$dirName = realpath($dirName);
if ( ! file_exists($dirName)) {
throw new \InvalidArgumentException(
sprintf("Mapping directory '<info>%s</info>' does not exist.", $dirName)
);
} else if ( ! is_readable($dirName)) {
throw new \InvalidArgumentException(
sprintf("Mapping directory '<info>%s</info>' does not have read permissions.", $dirName)
);
}
$reader->addMappingSource($dirName);
}
$metadatas = $em->getMetadataFactory()->getAllMetadata();
$metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter'));
// Process destination directory
$destPath = realpath($input->getArgument('dest-path'));
@ -132,23 +111,20 @@ EOT
);
}
// Create EntityGenerator
$entityGenerator = new EntityGenerator();
if ( count($metadatas)) {
// Create EntityGenerator
$entityGenerator = new EntityGenerator();
$entityGenerator->setGenerateAnnotations($input->getOption('generate-annotations'));
$entityGenerator->setGenerateStubMethods($input->getOption('generate-methods'));
$entityGenerator->setRegenerateEntityIfExists($input->getOption('regenerate-entities'));
$entityGenerator->setUpdateEntityIfExists($input->getOption('update-entities'));
$entityGenerator->setNumSpaces($input->getOption('num-spaces'));
$entityGenerator->setGenerateAnnotations($input->getOption('generate-annotations'));
$entityGenerator->setGenerateStubMethods($input->getOption('generate-methods'));
$entityGenerator->setRegenerateEntityIfExists($input->getOption('regenerate-entities'));
$entityGenerator->setUpdateEntityIfExists($input->getOption('update-entities'));
$entityGenerator->setNumSpaces($input->getOption('num-spaces'));
if (($extend = $input->getOption('extend')) !== null) {
$entityGenerator->setClassToExtend($extend);
}
if (($extend = $input->getOption('extend')) !== null) {
$entityGenerator->setClassToExtend($extend);
}
// Retrieving ClassMetadatas
$metadatas = $reader->getMetadatas();
if ( ! empty($metadatas)) {
foreach ($metadatas as $metadata) {
$output->write(
sprintf('Processing entity "<info>%s</info>"', $metadata->name) . PHP_EOL

View File

@ -23,7 +23,8 @@ namespace Doctrine\ORM\Tools\Console\Command;
use Symfony\Components\Console\Input\InputArgument,
Symfony\Components\Console\Input\InputOption,
Symfony\Components\Console;
Symfony\Components\Console,
Doctrine\ORM\Tools\Console\MetadataFilter;
/**
* Command to (re)generate the proxy classes used by doctrine.
@ -48,18 +49,14 @@ class GenerateProxiesCommand extends Console\Command\Command
->setName('orm:generate-proxies')
->setDescription('Generates proxy classes for entity classes.')
->setDefinition(array(
new InputArgument(
'from-path', InputArgument::REQUIRED, 'The path of mapping information.'
new InputOption(
'filter', null, InputOption::PARAMETER_REQUIRED | InputOption::PARAMETER_IS_ARRAY,
'A string pattern used to match entities that should be processed.'
),
new InputArgument(
'dest-path', InputArgument::OPTIONAL,
'The path to generate your proxy classes. If none is provided, it will attempt to grab from configuration.'
),
new InputOption(
'from', null, InputOption::PARAMETER_REQUIRED | InputOption::PARAMETER_IS_ARRAY,
'Optional paths of mapping information.',
array()
)
))
->setHelp(<<<EOT
Generates proxy classes for entity classes.
@ -73,28 +70,9 @@ EOT
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
{
$em = $this->getHelper('em')->getEntityManager();
$reader = new ClassMetadataReader();
$reader->setEntityManager($em);
// Process source directories
$fromPaths = array_merge(array($input->getArgument('from-path')), $input->getOption('from'));
foreach ($fromPaths as $dirName) {
$dirName = realpath($dirName);
if ( ! file_exists($dirName)) {
throw new \InvalidArgumentException(
sprintf("Mapping directory '<info>%s</info>' does not exist.", $dirName)
);
} else if ( ! is_readable($dirName)) {
throw new \InvalidArgumentException(
sprintf("Mapping directory '<info>%s</info>' does not have read permissions.", $dirName)
);
}
$reader->addMappingSource($dirName);
}
$metadatas = $em->getMetadataFactory()->getAllMetadata();
$metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter'));
// Process destination directory
if (($destPath = $input->getArgument('dest-path')) === null) {
@ -113,10 +91,7 @@ EOT
);
}
// Retrieving ClassMetadatas
$metadatas = $reader->getMetadatas();
if ( ! empty($metadatas)) {
if ( count($metadatas)) {
foreach ($metadatas as $metadata) {
$output->write(
sprintf('Processing entity "<info>%s</info>"', $metadata->name) . PHP_EOL

View File

@ -23,7 +23,8 @@ namespace Doctrine\ORM\Tools\Console\Command;
use Symfony\Components\Console\Input\InputArgument,
Symfony\Components\Console\Input\InputOption,
Symfony\Components\Console;
Symfony\Components\Console,
Doctrine\ORM\Tools\Console\MetadataFilter;
/**
* Command to generate repository classes for mapping information.
@ -65,16 +66,12 @@ class <className> extends EntityRepository
->setName('orm:generate-repositories')
->setDescription('Generate repository classes from your mapping information.')
->setDefinition(array(
new InputArgument(
'from-path', InputArgument::REQUIRED, 'The path of mapping information.'
new InputOption(
'filter', null, InputOption::PARAMETER_REQUIRED | InputOption::PARAMETER_IS_ARRAY,
'A string pattern used to match entities that should be processed.'
),
new InputArgument(
'dest-path', InputArgument::REQUIRED, 'The path to generate your repository classes.'
),
new InputOption(
'from', null, InputOption::PARAMETER_REQUIRED | InputOption::PARAMETER_IS_ARRAY,
'Optional paths of mapping information.',
array()
)
))
->setHelp(<<<EOT
@ -89,28 +86,9 @@ EOT
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
{
$em = $this->getHelper('em')->getEntityManager();
$reader = new ClassMetadataReader();
$reader->setEntityManager($em);
// Process source directories
$fromPaths = array_merge(array($input->getArgument('from-path')), $input->getOption('from'));
foreach ($fromPaths as $dirName) {
$dirName = realpath($dirName);
if ( ! file_exists($dirName)) {
throw new \InvalidArgumentException(
sprintf("Mapping directory '<info>%s</info>' does not exist.", $dirName)
);
} else if ( ! is_readable($dirName)) {
throw new \InvalidArgumentException(
sprintf("Mapping directory '<info>%s</info>' does not have read permissions.", $dirName)
);
}
$reader->addMappingSource($dirName);
}
$metadatas = $em->getMetadataFactory()->getAllMetadata();
$metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter'));
// Process destination directory
$destPath = realpath($input->getArgument('dest-path'));
@ -125,10 +103,7 @@ EOT
);
}
// Retrieving ClassMetadatas
$metadatas = $reader->getMetadatas();
if ( ! empty($metadatas)) {
if ( count($metadatas)) {
$numRepositories = 0;
foreach ($metadatas as $metadata) {

View File

@ -0,0 +1,64 @@
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Tools\Console\Command\SchemaTool;
use Symfony\Components\Console\Input\InputArgument,
Symfony\Components\Console\Input\InputOption,
Symfony\Components\Console\Input\InputInterface,
Symfony\Components\Console\Output\OutputInterface,
Symfony\Components\Console\Command\Command,
Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper,
Doctrine\ORM\Tools\SchemaTool,
Doctrine\ORM\Mapping\Driver\AbstractFileDriver;
abstract class AbstractCommand extends Command
{
/**
* @param InputInterface $input
* @param OutputInterface $output
* @param SchemaTool $schemaTool
* @param array $metadatas
*/
abstract protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas);
/**
* @see Console\Command\Command
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$emHelper = $this->getHelper('em');
/* @var $em \Doctrine\ORM\EntityManager */
$em = $emHelper->getEntityManager();
$metadatas = $em->getMetadataFactory()->getAllMetadata();
if ( ! empty($metadatas)) {
// Create SchemaTool
$tool = new \Doctrine\ORM\Tools\SchemaTool($em);
$this->executeSchemaCommand($input, $output, $tool, $metadatas);
} else {
$output->write('No Metadata Classes to process.' . PHP_EOL);
}
}
}

View File

@ -23,7 +23,9 @@ namespace Doctrine\ORM\Tools\Console\Command\SchemaTool;
use Symfony\Components\Console\Input\InputArgument,
Symfony\Components\Console\Input\InputOption,
Symfony\Components\Console;
Symfony\Components\Console\Input\InputInterface,
Symfony\Components\Console\Output\OutputInterface,
Doctrine\ORM\Tools\SchemaTool;
/**
* Command to create the database schema for a set of classes based on their mappings.
@ -37,7 +39,7 @@ use Symfony\Components\Console\Input\InputArgument,
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class CreateCommand extends Console\Command\Command
class CreateCommand extends AbstractCommand
{
/**
* @see Console\Command\Command
@ -50,14 +52,6 @@ class CreateCommand extends Console\Command\Command
'Processes the schema and either create it directly on EntityManager Storage Connection or generate the SQL output.'
)
->setDefinition(array(
new InputArgument(
'from-path', InputArgument::REQUIRED, 'The path of mapping information.'
),
new InputOption(
'from', null, InputOption::PARAMETER_REQUIRED | InputOption::PARAMETER_IS_ARRAY,
'Optional paths of mapping information.',
array()
),
new InputOption(
'dump-sql', null, InputOption::PARAMETER_NONE,
'Instead of try to apply generated SQLs into EntityManager Storage Connection, output them.'
@ -69,52 +63,15 @@ EOT
);
}
/**
* @see Console\Command\Command
*/
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas)
{
$em = $this->getHelper('em')->getEntityManager();
$reader = new \Doctrine\ORM\Tools\ClassMetadataReader();
$reader->setEntityManager($em);
// Process source directories
$fromPaths = array_merge(array($input->getArgument('from-path')), $input->getOption('from'));
foreach ($fromPaths as $dirName) {
$dirName = realpath($dirName);
if ( ! file_exists($dirName)) {
throw new \InvalidArgumentException(
sprintf("Mapping directory '<info>%s</info>' does not exist.", $dirName)
);
} else if ( ! is_readable($dirName)) {
throw new \InvalidArgumentException(
sprintf("Mapping directory '<info>%s</info>' does not have read permissions.", $dirName)
);
}
$reader->addMappingSource($dirName);
}
// Retrieving ClassMetadatas
$metadatas = $reader->getMetadatas();
if ( ! empty($metadatas)) {
// Create SchemaTool
$tool = new \Doctrine\ORM\Tools\SchemaTool($em);
if ($input->getOption('dump-sql') === null) {
$sqls = $tool->getCreateSchemaSql($metadatas);
$output->write(implode(';' . PHP_EOL, $sqls));
} else {
$output->write('Creating database schema...' . PHP_EOL);
$tool->createSchema($metadatas);
$output->write('Database schema created successfully!' . PHP_EOL);
}
if ($input->getOption('dump-sql') === true) {
$sqls = $schemaTool->getCreateSchemaSql($metadatas);
$output->write(implode(';' . PHP_EOL, $sqls) . PHP_EOL);
} else {
$output->write('No Metadata Classes to process.' . PHP_EOL);
$output->write('Creating database schema...' . PHP_EOL);
$schemaTool->createSchema($metadatas);
$output->write('Database schema created successfully!' . PHP_EOL);
}
}
}

View File

@ -23,7 +23,9 @@ namespace Doctrine\ORM\Tools\Console\Command\SchemaTool;
use Symfony\Components\Console\Input\InputArgument,
Symfony\Components\Console\Input\InputOption,
Symfony\Components\Console;
Symfony\Components\Console\Input\InputInterface,
Symfony\Components\Console\Output\OutputInterface,
Doctrine\ORM\Tools\SchemaTool;
/**
* Command to drop the database schema for a set of classes based on their mappings.
@ -37,7 +39,7 @@ use Symfony\Components\Console\Input\InputArgument,
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class DropCommand extends Console\Command\Command
class DropCommand extends AbstractCommand
{
/**
* @see Console\Command\Command
@ -50,14 +52,6 @@ class DropCommand extends Console\Command\Command
'Processes the schema and either drop the database schema of EntityManager Storage Connection or generate the SQL output.'
)
->setDefinition(array(
new InputArgument(
'from-path', InputArgument::REQUIRED, 'The path of mapping information.'
),
new InputOption(
'from', null, InputOption::PARAMETER_REQUIRED | InputOption::PARAMETER_IS_ARRAY,
'Optional paths of mapping information.',
array()
),
new InputOption(
'dump-sql', null, InputOption::PARAMETER_NONE,
'Instead of try to apply generated SQLs into EntityManager Storage Connection, output them.'
@ -70,52 +64,15 @@ EOT
);
}
/**
* @see Console\Command\Command
*/
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas)
{
$em = $this->getHelper('em')->getEntityManager();
$reader = new \Doctrine\ORM\Tools\ClassMetadataReader();
$reader->setEntityManager($em);
// Process source directories
$fromPaths = array_merge(array($input->getArgument('from-path')), $input->getOption('from'));
foreach ($fromPaths as $dirName) {
$dirName = realpath($dirName);
if ( ! file_exists($dirName)) {
throw new \InvalidArgumentException(
sprintf("Mapping directory '<info>%s</info>' does not exist.", $dirName)
);
} else if ( ! is_readable($dirName)) {
throw new \InvalidArgumentException(
sprintf("Mapping directory '<info>%s</info>' does not have read permissions.", $dirName)
);
}
$reader->addMappingSource($dirName);
}
// Retrieving ClassMetadatas
$metadatas = $reader->getMetadatas();
if ( ! empty($metadatas)) {
// Create SchemaTool
$tool = new \Doctrine\ORM\Tools\SchemaTool($em);
if ($input->getOption('dump-sql') === null) {
$sqls = $tool->getDropSchemaSql($metadatas);
$output->write(implode(';' . PHP_EOL, $sqls));
} else {
$output->write('Dropping database schema...' . PHP_EOL);
$tool->dropSchema($metadatas);
$output->write('Database schema dropped successfully!' . PHP_EOL);
}
if ($input->getOption('dump-sql') === true) {
$sqls = $schemaTool->getDropSchemaSql($metadatas);
$output->write(implode(';' . PHP_EOL, $sqls) . PHP_EOL);
} else {
$output->write('No Metadata Classes to process.' . PHP_EOL);
$output->write('Dropping database schema...' . PHP_EOL);
$schemaTool->dropSchema($metadatas);
$output->write('Database schema dropped successfully!' . PHP_EOL);
}
}
}

View File

@ -23,7 +23,9 @@ namespace Doctrine\ORM\Tools\Console\Command\SchemaTool;
use Symfony\Components\Console\Input\InputArgument,
Symfony\Components\Console\Input\InputOption,
Symfony\Components\Console;
Symfony\Components\Console\Input\InputInterface,
Symfony\Components\Console\Output\OutputInterface,
Doctrine\ORM\Tools\SchemaTool;
/**
* Command to update the database schema for a set of classes based on their mappings.
@ -37,7 +39,7 @@ use Symfony\Components\Console\Input\InputArgument,
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class UpdateCommand extends Console\Command\Command
class UpdateCommand extends AbstractCommand
{
/**
* @see Console\Command\Command
@ -50,14 +52,6 @@ class UpdateCommand extends Console\Command\Command
'Processes the schema and either update the database schema of EntityManager Storage Connection or generate the SQL output.'
)
->setDefinition(array(
new InputArgument(
'from-path', InputArgument::REQUIRED, 'The path of mapping information.'
),
new InputOption(
'from', null, InputOption::PARAMETER_REQUIRED | InputOption::PARAMETER_IS_ARRAY,
'Optional paths of mapping information.',
array()
),
new InputOption(
'complete', null, InputOption::PARAMETER_NONE,
'If defined, all assets of the database which are not relevant to the current metadata will be dropped.'
@ -75,55 +69,18 @@ EOT
);
}
/**
* @see Console\Command\Command
*/
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas)
{
$em = $this->getHelper('em')->getEntityManager();
$reader = new \Doctrine\ORM\Tools\ClassMetadataReader();
$reader->setEntityManager($em);
// Process source directories
$fromPaths = array_merge(array($input->getArgument('from-path')), $input->getOption('from'));
foreach ($fromPaths as $dirName) {
$dirName = realpath($dirName);
if ( ! file_exists($dirName)) {
throw new \InvalidArgumentException(
sprintf("Mapping directory '<info>%s</info>' does not exist.", $dirName)
);
} else if ( ! is_readable($dirName)) {
throw new \InvalidArgumentException(
sprintf("Mapping directory '<info>%s</info>' does not have read permissions.", $dirName)
);
}
$reader->addMappingSource($dirName);
}
// Defining if update is complete or not (--complete not defined means $saveMode = true)
$saveMode = ($input->getOption('complete') === null);
$saveMode = ($input->getOption('complete') === true);
// Retrieving ClassMetadatas
$metadatas = $reader->getMetadatas();
if ( ! empty($metadatas)) {
// Create SchemaTool
$tool = new \Doctrine\ORM\Tools\SchemaTool($em);
if ($input->getOption('dump-sql') === null) {
$sqls = $tool->getUpdateSchemaSql($metadatas, $saveMode);
$output->write(implode(';' . PHP_EOL, $sqls));
} else {
$output->write('Updating database schema...' . PHP_EOL);
$tool->updateSchema($metadatas, $saveMode);
$output->write('Database schema updated successfully!' . PHP_EOL);
}
if ($input->getOption('dump-sql') === true) {
$sqls = $schemaTool->getUpdateSchemaSql($metadatas, $saveMode);
$output->write(implode(';' . PHP_EOL, $sqls) . PHP_EOL);
} else {
$output->write('No Metadata Classes to process.' . PHP_EOL);
$output->write('Updating database schema...' . PHP_EOL);
$schemaTool->updateSchema($metadatas, $saveMode);
$output->write('Database schema updated successfully!' . PHP_EOL);
}
}
}

View File

@ -0,0 +1,80 @@
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Tools\Console;
/**
* Used by CLI Tools to restrict entity-based commands to given patterns.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.com
* @since 1.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class MetadataFilter extends \FilterIterator implements \Countable
{
/**
* Filter Metadatas by one or more filter options.
*
* @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;
parent::__construct($metadata);
}
public function accept()
{
if (count($this->_filter) == 0) {
return true;
}
$it = $this->getInnerIterator();
$metadata = $it->current();
foreach ($this->_filter AS $filter) {
if (strpos($metadata->name, $filter) !== false) {
return true;
}
}
return false;
}
public function count()
{
return count($this->getInnerIterator());
}
}

View File

@ -78,6 +78,7 @@ class EntityManagerMock extends \Doctrine\ORM\EntityManager
$config = new \Doctrine\ORM\Configuration();
$config->setProxyDir(__DIR__ . '/../Proxies');
$config->setProxyNamespace('Doctrine\Tests\Proxies');
$config->setMetadataDriverImpl(\Doctrine\ORM\Mapping\Driver\AnnotationDriver::create());
}
if (is_null($eventManager)) {
$eventManager = new \Doctrine\Common\EventManager();

View File

@ -83,7 +83,7 @@ class QueryCacheTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function testQueryCache_NoHitSaveParserResult()
{
$this->_em->getConfiguration()->setQueryCacheImpl(null);
$this->_em->getConfiguration()->setQueryCacheImpl(new ArrayCache());
$query = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux');
@ -103,7 +103,7 @@ class QueryCacheTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function testQueryCache_HitDoesNotSaveParserResult()
{
$this->_em->getConfiguration()->setQueryCacheImpl(null);
$this->_em->getConfiguration()->setQueryCacheImpl(new ArrayCache());
$query = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux');

View File

@ -82,7 +82,7 @@ class ResultCacheTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertTrue($cache->contains('testing_result_cache_id'));
$this->_em->getConfiguration()->setResultCacheImpl(null);
$this->_em->getConfiguration()->setResultCacheImpl(new ArrayCache());
}
public function testNativeQueryResultCaching()

View File

@ -221,7 +221,7 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
}
if (is_null(self::$_queryCacheImpl)) {
self::$_queryCacheImpl = new \Doctrine\Common\Cache\ArrayCache;
self::$_queryCacheImpl = new \Doctrine\Common\Cache\ArrayCache;
}
$this->_sqlLoggerStack = new \Doctrine\DBAL\Logging\DebugStack();
@ -234,6 +234,8 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
$config->setQueryCacheImpl(self::$_queryCacheImpl);
$config->setProxyDir(__DIR__ . '/Proxies');
$config->setProxyNamespace('Doctrine\Tests\Proxies');
$config->setMetadataDriverImpl($config->newDefaultAnnotationDriver());
$conn = $this->sharedFixture['conn'];
$conn->getConfiguration()->setSQLLogger($this->_sqlLoggerStack);

View File

@ -30,6 +30,9 @@ abstract class OrmTestCase extends DoctrineTestCase
} else {
$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
}
$config->setMetadataDriverImpl($config->newDefaultAnnotationDriver());
$config->setQueryCacheImpl(self::getSharedQueryCacheImpl());
$config->setProxyDir(__DIR__ . '/Proxies');
$config->setProxyNamespace('Doctrine\Tests\Proxies');

View File

@ -10,6 +10,9 @@ $classLoader->register();
$config = new \Doctrine\ORM\Configuration();
$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
$driverImpl = $config->newDefaultAnnotationDriver(array(__DIR__."/Entities"));
$config->setMetadataDriverImpl($driverImpl);
$config->setProxyDir(__DIR__ . '/Proxies');
$config->setProxyNamespace('Proxies');

View File

@ -30,11 +30,14 @@ $proxiesClassLoader->register();
$config = new Configuration;
$cache = new ApcCache;
$config->setMetadataCacheImpl($cache);
$driverImpl = $config->newDefaultAnnotationDriver(array(__DIR__."/Entities"));
$config->setMetadataDriverImpl($driverImpl);
$config->setQueryCacheImpl($cache);
// Proxy configuration
$config->setProxyDir(__DIR__ . '/Proxies');
$config->setProxyNamespace('Proxies');
$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
// Database connection information
$connectionOptions = array(