Commit bf0cfba2 authored by guilhermeblanco's avatar guilhermeblanco

[2.0] Incorporated CLI refactorings. Added support to namespaces and unlimited...

[2.0] Incorporated CLI refactorings. Added support to namespaces and unlimited depth namespaces. Dropped globalArguments for now, since they interfer in DAG implementation.
parent 60b9fb7c
...@@ -6,8 +6,12 @@ ...@@ -6,8 +6,12 @@
## CLI Controller changes ## CLI Controller changes
CLI main object changed its name and namespace. Renamed from Doctrine\ORM\Tools\Cli to Doctrine\ORM\Tools\Cli\CliController. CLI main object changed its name and namespace. Renamed from Doctrine\ORM\Tools\Cli to Doctrine\Common\Cli\CliController.
Doctrine\ORM\Tools\Cli\CliController methods addTasks and addTask are now fluent. Doctrine\Common\Cli\CliController now only deals with namespaces. Ready to go, Core, Dbal and Orm are available and you can subscribe new tasks by retrieving the namespace and including new task. Example:
[php]
$cli->getNamespace('Core')->addTask('my-example', '\MyProject\Tools\Cli\Tasks\MyExampleTask');
## CLI Tasks documentation ## CLI Tasks documentation
......
<?php <?php
require 'Doctrine/Common/ClassLoader.php'; require_once __DIR__ . '/../lib/Doctrine/Common/ClassLoader.php';
$classLoader = new \Doctrine\Common\ClassLoader('Doctrine'); $classLoader = new \Doctrine\Common\ClassLoader('Doctrine');
$classLoader->setIncludePath(__DIR__ . '/../lib');
$classLoader->register(); $classLoader->register();
$cli = new \Doctrine\ORM\Tools\Cli\CliController(); $configuration = new \Doctrine\Common\Cli\Configuration();
$cli = new \Doctrine\Common\Cli\CliController($configuration);
$cli->run($_SERVER['argv']); $cli->run($_SERVER['argv']);
\ No newline at end of file
<?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\Common\Cli;
use Doctrine\Common\Util\Inflector,
Doctrine\Common\DoctrineException;
/**
* Abstract CLI Namespace class
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.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>
*/
abstract class AbstractNamespace
{
/**
* @var Configuration CLI Configuration instance
*/
private $_configuration = null;
/**
* @var AbstractPrinter CLI Printer instance
*/
private $_printer = null;
/**
* @var AbstractNamespace CLI Namespace instance
*/
private $_parentNamespace = null;
/**
* @var array Available namespaces
*/
private $_namespaces = array();
/**
* Add a single namespace to CLI.
* Example of inclusion support to a single namespace:
*
* [php]
* $cliOrmNamespace->addNamespace('my-custom-namespace');
*
* @param string $name CLI Namespace name
*
* @return CliController This object instance
*/
public function addNamespace($name)
{
$name = self::formatName($name);
if ($this->hasNamespace($name)) {
throw DoctrineException::cannotOverrideNamespace($name);
}
return $this->overrideNamespace($name);
}
/**
* Overrides a namespace to CLI.
* Example of inclusion support to a single namespace:
*
* [php]
* $cli->overrideNamespace('orm');
*
* @param string $name CLI Namespace name
*
* @return AbstractNamespace Newly created CLI Namespace
*/
public function overrideNamespace($name)
{
$taskNamespace = new TaskNamespace($name);
$taskNamespace->setParentNamespace($this);
$taskNamespace->setPrinter($this->_printer);
$taskNamespace->setConfiguration($this->_configuration);
$this->_namespaces[$taskNamespace->getName()] = $taskNamespace;
return $taskNamespace;
}
/**
* Retrieve CLI Namespace.
* Example of usage:
*
* [php]
* $cliOrmNamespace = $cli->getNamespace('ORM');
*
* @param string $name CLI Namespace name
*
* @return TaskNamespace CLI Namespace
*/
public function getNamespace($name)
{
$name = self::formatName($name);
return isset($this->_namespaces[$name])
? $this->_namespaces[$name] : null;
}
/**
* Check existance of a CLI Namespace
*
* @param string CLI Namespace name
*
* @return boolean TRUE if namespace if defined, false otherwise
*/
public function hasNamespace($name)
{
return ($this->getNamespace($name) !== null);
}
/**
* Defines the parent CLI Namespace
*
* @return AbstractNamespace
*/
public function setParentNamespace(AbstractNamespace $namespace)
{
$this->_parentNamespace = $namespace;
return $this;
}
/**
* Retrieves currently parent CLI Namespace
*
* @return AbstractNamespace
*/
public function getParentNamespace()
{
return $this->_parentNamespace;
}
/**
* Retrieve all defined CLI Tasks
*
* @return array
*/
public function getAvailableTasks()
{
$tasks = array();
foreach ($this->_namespaces as $namespace) {
$tasks = array_merge($tasks, $namespace->getAvailableTasks());
}
return $tasks;
}
/**
* Defines the CLI Output Printer
*
* @param AbstractPrinter $printer CLI Output Printer
*
* @return AbstractNamespace
*/
public function setPrinter(Printers\AbstractPrinter $printer = null)
{
$this->_printer = $printer ?: new Printers\AnsiColorPrinter;
return $this;
}
/**
* Retrieves currently used CLI Output Printer
*
* @return AbstractPrinter
*/
public function getPrinter()
{
return $this->_printer;
}
/**
* Defines the CLI Configuration
*
* #param Configuration $configuration CLI Configuration
*
* @return AbstractNamespace
*/
public function setConfiguration(Configuration $config)
{
$this->_configuration = $config;
return $this;
}
/**
* Retrieves currently used CLI Configuration
*
* @return Configuration
*/
public function getConfiguration()
{
return $this->_configuration;
}
/**
* Formats the CLI Namespace name into a camel-cased name
*
* @param string $name CLI Namespace name
*
* @return string Formatted CLI Namespace name
*/
public static function formatName($name)
{
return Inflector::classify($name);
}
}
\ No newline at end of file
...@@ -19,12 +19,7 @@ ...@@ -19,12 +19,7 @@
* <http://www.doctrine-project.org>. * <http://www.doctrine-project.org>.
*/ */
namespace Doctrine\ORM\Tools\Cli; namespace Doctrine\Common\Cli;
use Doctrine\Common\Util\Inflector,
Doctrine\Common\Cli\Printers\AbstractPrinter,
Doctrine\Common\Cli\Printers\AnsiColorPrinter,
Doctrine\ORM\Tools\Cli\Tasks\AbstractTask;
/** /**
* Generic CLI Controller of Tasks execution * Generic CLI Controller of Tasks execution
...@@ -40,86 +35,60 @@ use Doctrine\Common\Util\Inflector, ...@@ -40,86 +35,60 @@ use Doctrine\Common\Util\Inflector,
* public function validate(); * public function validate();
* } * }
* *
* And then, include the support to it in your command-line script: * And then, load the namespace assoaicated an include the support to it in your command-line script:
* *
* [php] * [php]
* $cli = new Doctrine\ORM\Tools\Cli\CliController(); * $cli = new Doctrine\Common\Cli\CliController();
* $cli->addTask('myTask', 'MyProject\Tools\Cli\Tasks\MyTask'); * $cliNS = $cli->getNamespace('custom');
* $cliNS->addTask('myTask', 'MyProject\Tools\Cli\Tasks\MyTask');
* *
* To execute, just type any classify-able name: * To execute, just type any classify-able name:
* *
* $ cli.php my-task * $ cli.php custom:my-task
* *
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org * @link www.doctrine-project.org
* @since 2.0 * @since 2.0
* @version $Revision$ * @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com> * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com> * @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
*/ */
class CliController class CliController extends AbstractNamespace
{ {
/**
* @var AbstractPrinter CLI Printer instance
*/
private $_printer = null;
/**
* @var array Available tasks
*/
private $_tasks = array();
/** /**
* The CLI processor of tasks * The CLI processor of tasks
* *
* @param AbstractPrinter $printer CLI Output printer * @param AbstractPrinter $printer CLI Output printer
*/ */
public function __construct(AbstractPrinter $printer = null) public function __construct(Configuration $config, AbstractPrinter $printer = null)
{ {
//$this->_printer = new Printer\Normal(); $this->setPrinter($printer);
$this->_printer = $printer ?: new AnsiColorPrinter; $this->setConfiguration($config);
// Include core tasks // Include core namespaces of tasks
$ns = 'Doctrine\ORM\Tools\Cli\Tasks'; $ns = '\Doctrine\Common\Cli\Tasks';
$this->addNamespace('Core')
$this->addTasks(array( ->addTask('help', $ns . '\HelpTask');
'help' => $ns . '\HelpTask',
'version' => $ns . '\VersionTask', $ns = '\Doctrine\ORM\Tools\Cli\Tasks';
'schema-tool' => $ns . '\SchemaToolTask', $this->addNamespace('Orm')
'run-sql' => $ns . '\RunSqlTask', ->addTask('clear-cache', $ns . '\ClearCacheTask')
'run-dql' => $ns . '\RunDqlTask', ->addTask('convert-mapping', $ns . '\ConvertMappingTask')
'convert-mapping' => $ns . '\ConvertMappingTask', ->addTask('ensure-production-settings', $ns . '\EnsureProductionSettingsTask')
'generate-proxies' => $ns . '\GenerateProxiesTask', ->addTask('generate-proxies', $ns . '\GenerateProxiesTask')
'clear-cache' => $ns . '\ClearCacheTask', ->addTask('run-dql', $ns . '\RunDqlTask')
'ensure-production-settings' => $ns . '\EnsureProductionSettingsTask' ->addTask('schema-tool', $ns . '\SchemaToolTask')
)); ->addTask('version', $ns . '\VersionTask');
$ns = '\Doctrine\DBAL\Tools\Cli\Tasks';
$this->addNamespace('Dbal')
->addTask('run-sql', $ns . '\RunSqlTask');
} }
/** /**
* Add a collection of tasks to the CLI. * Add a single task to CLI Core Namespace. This method acts as a delegate.
* To include them, just call the method with the following structure:
*
* [php]
* $cli->addTasks(array(
* 'my-custom-task' => 'MyProject\Cli\Tasks\MyCustomTask',
* ...
* ));
*
* @param array $tasks CLI Tasks to be included
* @return CliController This object instance
*/
public function addTasks($tasks)
{
foreach ($tasks as $name => $class) {
$this->addTask($name, $class);
}
return $this;
}
/**
* Add a single task to CLI.
* Example of inclusion support to a single task: * Example of inclusion support to a single task:
* *
* [php] * [php]
...@@ -127,15 +96,12 @@ class CliController ...@@ -127,15 +96,12 @@ class CliController
* *
* @param string $name CLI Task name * @param string $name CLI Task name
* @param string $class CLI Task class (FQCN - Fully Qualified Class Name) * @param string $class CLI Task class (FQCN - Fully Qualified Class Name)
*
* @return CliController This object instance * @return CliController This object instance
*/ */
public function addTask($name, $class) public function addTask($name, $class)
{ {
// Convert $name into a class equivalent $this->getNamespace('Core')->addTask($name, $class);
// (ie. 'show_version' => 'showVersion')
$name = $this->_processTaskName($name);
$this->_tasks[$name] = $class;
return $this; return $this;
} }
...@@ -151,70 +117,52 @@ class CliController ...@@ -151,70 +117,52 @@ class CliController
// Remove script file argument // Remove script file argument
$scriptFile = array_shift($args); $scriptFile = array_shift($args);
// Automatically prepend 'help' task if: // If not arguments are defined, include "help"
// 1- No arguments were passed if (empty($args)) {
// 2- First item is not a valid task name array_unshift($args, 'Core:Help');
if (empty($args) || ! isset($this->_tasks[$this->_processTaskName($args[0])])) {
array_unshift($args, 'help');
} }
// Process all sent arguments // Process all sent arguments
$processedArgs = $this->_processArguments($args); $args = $this->_processArguments($args);
try { try {
$this->_printer->writeln('Doctrine Command Line Interface' . PHP_EOL, 'HEADER'); $this->getPrinter()->writeln('Doctrine Command Line Interface' . PHP_EOL, 'HEADER');
// Handle possible multiple tasks on a single command // Handle possible multiple tasks on a single command
foreach($processedArgs as $taskData) { foreach($args as $taskData) {
// Retrieve the task name and arguments $taskName = $taskData['name'];
$taskName = $this->_processTaskName($taskData['name']);
$taskArguments = $taskData['args']; $taskArguments = $taskData['args'];
// Check if task exists $this->runTask($taskName, $taskArguments);
if (isset($this->_tasks[$taskName]) && class_exists($this->_tasks[$taskName], true)) {
// Initializing EntityManager
$em = $this->_initializeEntityManager($processedArgs, $taskArguments);
// Instantiate and execute the task
$task = new $this->_tasks[$taskName]($this->_printer);
$task->setAvailableTasks($this->_tasks);
$task->setEntityManager($em);
$task->setArguments($taskArguments);
if (
(isset($taskArguments['help']) && $taskArguments['help']) ||
(isset($taskArguments['h']) && $taskArguments['h'])
) {
$task->extendedHelp(); // User explicitly asked for help option
} else if ($this->_isTaskValid($task)) {
$task->run();
} else {
$this->_printer->write(PHP_EOL);
$task->basicHelp(); // Fallback of not-valid task arguments
$this->_printer->write(PHP_EOL);
}
} else {
throw \Doctrine\Common\DoctrineException::taskDoesNotExist($taskName);
} }
} catch (\Exception $e) {
$message = $taskName . ' => ' . $e->getMessage();
if (isset($taskArguments['trace']) && $taskArguments['trace']) {
$message .= PHP_EOL . PHP_EOL . $e->getTraceAsString();
} }
} catch (\Doctrine\Common\DoctrineException $e) {
$this->_printer->writeln( $this->getPrinter()->writeln($message, 'ERROR');
$taskName . ': ' . $e->getMessage() . PHP_EOL . PHP_EOL . $e->getTraceAsString(), 'ERROR'
);
} }
} }
/** /**
* Processes the given task name and return it formatted * Executes a given CLI Task
* *
* @param string $taskName Task name * @param atring $name CLI Task name
* @return string * @param array $args CLI Arguments
*/ */
private function _processTaskName($taskName) public function runTask($name, $args = array())
{ {
$taskName = str_replace('-', '_', $taskName); // Retrieve namespace name, task name and arguments
$taskPath = explode(':', $name);
return Inflector::classify($taskName); // Find the correct namespace where the task is defined
$taskName = array_pop($taskPath);
$taskNamespace = $this->_retrieveTaskNamespace($taskPath);
$taskNamespace->runTask($taskName, $args);
} }
/** /**
...@@ -248,10 +196,10 @@ class CliController ...@@ -248,10 +196,10 @@ class CliController
* ) * )
* *
* Based on implementation of Patrick Fisher <patrick@pwfisher.com> available at: * Based on implementation of Patrick Fisher <patrick@pwfisher.com> available at:
*
* http://pwfisher.com/nucleus/index.php?itemid=45 * http://pwfisher.com/nucleus/index.php?itemid=45
* *
* @param array $args * @param array $args
*
* @return array * @return array
*/ */
private function _processArguments($args = array()) private function _processArguments($args = array())
...@@ -274,8 +222,9 @@ class CliController ...@@ -274,8 +222,9 @@ class CliController
} else { } else {
$key = substr($arg, 2, $eqPos - 2); $key = substr($arg, 2, $eqPos - 2);
$value = substr($arg, $eqPos + 1); $value = substr($arg, $eqPos + 1);
$value = (strpos($value, ' ') !== false) ? $value $value = (strpos($value, ' ') !== false) ? $value : array_values(array_filter(
: array_values(array_filter(explode(',', $value), function ($v) { return trim($v) != ''; })); explode(',', $value), function ($v) { return trim($v) != ''; }
));
$out[$key] = ( ! is_array($value) || (is_array($value) && count($value) > 1)) $out[$key] = ( ! is_array($value) || (is_array($value) && count($value) > 1))
? $value : $value[0]; ? $value : $value[0];
} }
...@@ -285,8 +234,9 @@ class CliController ...@@ -285,8 +234,9 @@ class CliController
if (substr($arg, 2, 1) == '='){ if (substr($arg, 2, 1) == '='){
$key = substr($arg, 1, 1); $key = substr($arg, 1, 1);
$value = substr($arg, 3); $value = substr($arg, 3);
$value = (strpos($value, ' ') !== false) ? $value $value = (strpos($value, ' ') !== false) ? $value : array_values(array_filter(
: array_values(array_filter(explode(',', $value), function ($v) { return trim($v) != ''; })); explode(',', $value), function ($v) { return trim($v) != ''; }
));
$out[$key] = ( ! is_array($value) || (is_array($value) && count($value) > 1)) $out[$key] = ( ! is_array($value) || (is_array($value) && count($value) > 1))
? $value : $value[0]; ? $value : $value[0];
// -abc // -abc
...@@ -313,52 +263,35 @@ class CliController ...@@ -313,52 +263,35 @@ class CliController
} }
/** /**
* Checks if CLI Task is valid based on given arguments. * Retrieve the correct namespace given a namespace path
* *
* @param AbstractTask $task CLI Task instance * @param array $namespacePath CLI Namespace path
*/
private function _isTaskValid(AbstractTask $task)
{
// TODO: Should we change the behavior and check for
// required and optional arguments here?
return $task->validate();
}
/**
* Initialized Entity Manager for Tasks
* *
* @param array CLI Task arguments * @return AbstractNamespace
* @return EntityManager
*/ */
private function _initializeEntityManager(array $args, array &$taskArgs) private function _retrieveTaskNamespace($namespacePath)
{ {
// Initialize EntityManager $taskNamespace = $this;
$configFile = ( ! isset($taskArgs['config'])) ? './cli-config.php' : $taskArgs['config']; $currentNamespacePath = '';
if (file_exists($configFile)) {
// Including configuration file
require $configFile;
// Check existance of EntityManager // Consider possible missing namespace (ie. "help") and forward to "core"
if ( ! isset($em)) { if (count($namespacePath) == 0) {
throw new \Doctrine\Common\DoctrineException( $namespacePath = array('Core');
'No EntityManager created in configuration'
);
} }
// Check for gloal argument options here // Loop through each namespace
if (isset($globalArguments)) { foreach ($namespacePath as $namespaceName) {
// Merge arguments. Values specified via the CLI take preference. $taskNamespace = $taskNamespace->getNamespace($namespaceName);
$taskArgs = array_merge($globalArguments, $taskArgs);
// If the given namespace returned "null", throw exception
if ($taskNamespace === null) {
throw CliException::namespaceDoesNotExist($namespaceName, $currentNamespacePath);
} }
return $em; $currentNamespacePath = (( ! empty($currentNamespacePath)) ? ':' : '')
} else { . $taskNamespace->getName();
throw new \Doctrine\Common\DoctrineException(
'Requested configuration file [' . $configFile . '] does not exist'
);
} }
return null; return $taskNamespace;
} }
} }
\ No newline at end of file
<?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\Common\Cli;
use Doctrine\Common\DoctrineException;
/**
* CLI Exception class
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.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 CliException extends DoctrineException
{
public static function namespaceDoesNotExist($namespaceName, $namespacePath = '')
{
return new self(
"Namespace '{$namespaceName}' does not exist" .
(( ! empty($namespacePath)) ? " in '{$namespacePath}'." : '.')
);
}
public static function taskDoesNotExist($taskName, $namespacePath)
{
return new self("Task '{$taskName}' does not exist in '{$namespacePath}'.");
}
public static function cannotOverrideTask($taskName)
{
return new self("Task '{$taskName}' cannot be overriden.");
}
}
\ No newline at end of file
<?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\Common\Cli;
/**
* CLI Configuration class
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.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 Configuration
{
/**
* @var array Configuration attributes
*/
private $_attributes = array();
/**
* Defines a new configuration attribute
*
* @param string $name Attribute name
* @param mixed $value Attribute value
*
* @return Configuration This object instance
*/
public function setAttribute($name, $value = null)
{
$this->_attributes[$name] = $value;
if ($value === null) {
unset($this->_attributes[$name]);
}
return $this;
}
/**
* Retrieves a configuration attribute
*
* @param string $name Attribute name
*
* @return mixed Attribute value
*/
public function getAttribute($name)
{
return isset($this->_attributes[$name])
? $this->_attributes[$name] : null;
}
/**
* Checks if configuration attribute is defined
*
* @param string $name Attribute name
*
* @return boolean TRUE if attribute exists, FALSE otherwise
*/
public function hasAttribute($name)
{
return isset($this->_attribute[$name]);
}
}
\ No newline at end of file
...@@ -41,6 +41,9 @@ class TaskDocumentation ...@@ -41,6 +41,9 @@ class TaskDocumentation
/** @var AbstractPrinter CLI Printer */ /** @var AbstractPrinter CLI Printer */
private $_printer; private $_printer;
/** @var AbstractNamespace CLI Namespace */
private $_namespace;
/** @var string CLI Task name */ /** @var string CLI Task name */
private $_name; private $_name;
...@@ -53,14 +56,25 @@ class TaskDocumentation ...@@ -53,14 +56,25 @@ class TaskDocumentation
/** /**
* Constructs a new CLI Task Documentation * Constructs a new CLI Task Documentation
* *
* @param AbstractPrinter CLI Printer * @param AbstractNamespace CLI Namespace
*/ */
public function __construct(AbstractPrinter $printer) public function __construct(AbstractNamespace $namespace)
{ {
$this->_printer = $printer; $this->_namespace = $namespace;
$this->_printer = $namespace->getPrinter();
$this->_optionGroup = new OptionGroup(OptionGroup::CARDINALITY_M_N); $this->_optionGroup = new OptionGroup(OptionGroup::CARDINALITY_M_N);
} }
/**
* Retrieves the CLI Namespace
*
* @return AbstractNamespace
*/
public function getNamespace()
{
return $this->_namespace;
}
/** /**
* Defines the CLI Task name * Defines the CLI Task name
* *
...@@ -84,6 +98,16 @@ class TaskDocumentation ...@@ -84,6 +98,16 @@ class TaskDocumentation
return $this->_name; return $this->_name;
} }
/**
* Retrieves the full CLI Task name
*
* @return string Task full name
*/
public function getFullName()
{
return $this->getNamespace()->getFullName() . ':' . $this->_name;
}
/** /**
* Defines the CLI Task description * Defines the CLI Task description
* *
...@@ -139,7 +163,7 @@ class TaskDocumentation ...@@ -139,7 +163,7 @@ class TaskDocumentation
*/ */
public function getSynopsis() public function getSynopsis()
{ {
return $this->_printer->format($this->_name, 'KEYWORD') . ' ' return $this->_printer->format($this->getFullName(), 'KEYWORD') . ' '
. trim($this->_optionGroup->formatPlain($this->_printer)); . trim($this->_optionGroup->formatPlain($this->_printer));
} }
...@@ -153,7 +177,7 @@ class TaskDocumentation ...@@ -153,7 +177,7 @@ class TaskDocumentation
$printer = $this->_printer; $printer = $this->_printer;
return $printer->format('Task: ') return $printer->format('Task: ')
. $printer->format($this->_name, 'KEYWORD') . $printer->format($this->getFullName(), 'KEYWORD')
. $printer->format(PHP_EOL) . $printer->format(PHP_EOL)
. $printer->format('Synopsis: ') . $printer->format('Synopsis: ')
. $this->getSynopsis() . $this->getSynopsis()
......
<?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\Common\Cli;
/**
* CLI Namespace class
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.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 TaskNamespace extends AbstractNamespace
{
/**
* @var boolean CLI Tasks flag to check if they are already initialized
*/
private $_initialized = false;
/**
* @var string CLI Namespace full name
*/
private $_fullName = null;
/**
* @var string CLI Namespace name
*/
private $_name = null;
/**
* @var array Available tasks
*/
private $_tasks = array();
/**
* The CLI namespace
*
* @param string $name CLI Namespace name
*/
public function __construct($name)
{
$this->_name = self::formatName($name);
}
/**
* Retrieve an instantiated CLI Task by given its name.
*
* @param string $name CLI Task name
*
* @return AbstractTask
*/
public function getTask($name)
{
// Check if task exists in namespace
if ($this->hasTask($name)) {
$taskClass = $this->_tasks[self::formatName($name)];
return new $taskClass($this);
}
throw CliException::taskDoesNotExist($name, $this->getFullName());
}
/**
* Retrieve all CLI Task in this Namespace.
*
* @return array
*/
public function getTasks()
{
return $this->_tasks;
}
/**
* Retrieve all defined CLI Tasks
*
* @return array
*/
public function getAvailableTasks()
{
$tasks = parent::getAvailableTasks();
foreach ($this->_tasks as $taskName => $taskClass) {
$fullName = $this->getFullName() . ':' . $taskName;
$tasks[$fullName] = $taskClass;
}
return $tasks;
}
/**
* Add a single task to CLI Namespace.
* Example of inclusion support to a single task:
*
* [php]
* $cliOrmNamespace->addTask('my-custom-task', 'MyProject\Cli\Tasks\MyCustomTask');
*
* @param string $name CLI Task name
* @param string $class CLI Task class (FQCN - Fully Qualified Class Name)
*
* @return TaskNamespace This object instance
*/
public function addTask($name, $class)
{
$name = self::formatName($name);
if ($this->hasTask($name)) {
throw DoctrineException::cannotOverrideTask($name);
}
return $this->overrideTask($name, $class);
}
/**
* Overrides task on CLI Namespace.
* Example of inclusion support to a single task:
*
* [php]
* $cliOrmNamespace->overrideTask('schema-tool', 'MyProject\Cli\Tasks\MyCustomTask');
*
* @param string $name CLI Task name
* @param string $class CLI Task class (FQCN - Fully Qualified Class Name)
*
* @return TaskNamespace This object instance
*/
public function overrideTask($name, $class)
{
$name = self::formatName($name);
$this->_tasks[$name] = $class;
return $this;
}
/**
* Check existance of a CLI Task
*
* @param string CLI Task name
*
* @return boolean TRUE if CLI Task if defined, false otherwise
*/
public function hasTask($name)
{
$name = self::formatName($name);
return isset($this->_tasks[$name]);
}
/**
* Retrieves the CLI Namespace name
*
* @return string CLI Namespace name
*/
public function getName()
{
return $this->_name;
}
/**
* Retrieves the full CLI Namespace name
*
* @return string CLI Namespace full name
*/
public function getFullName()
{
if ($this->_fullName === null) {
$str = $this->_name;
while (
($parentNamespace = $this->getParentNamespace()) !== null &&
! ($parentNamespace instanceof CliController)
) {
$str = $parentNamespace->getFullName() . ':' . $str;
}
$this->_fullName = $str;
}
return $this->_fullName;
}
/**
* Effectively instantiate and execute a given CLI Task
*
* @param string $name CLI Task name
* @param array $arguments CLI Task arguments
*/
public function runTask($name, $arguments = array())
{
try {
$task = $this->getTask($name);
$task->setArguments($arguments);
if ((isset($arguments['help']) && $arguments['help']) || (isset($arguments['h']) && $arguments['h'])) {
$task->extendedHelp(); // User explicitly asked for help option
} else if (isset($arguments['basic-help']) && $arguments['basic-help']) {
$task->basicHelp(); // User explicitly asked for basic help option
} else if ($task->validate()) {
$task->run();
}
} catch (DoctrineException $e) {
$message = $this->getFullName() . ':' . $name . ' => ' . $e->getMessage();
$printer = $this->getPrinter();
// If we want the trace of calls, append to error message
if (isset($arguments['trace']) && $arguments['trace']) {
$message .= PHP_EOL . PHP_EOL . $e->getTraceAsString();
}
$printer->writeln($messageMessage, 'ERROR');
// Unable instantiate task or task is not valid
if ($task !== null) {
$printer->write(PHP_EOL);
$task->basicHelp(); // Fallback of not-valid task arguments
}
$printer->write(PHP_EOL);
}
}
}
\ No newline at end of file
...@@ -19,29 +19,21 @@ ...@@ -19,29 +19,21 @@
* <http://www.doctrine-project.org>. * <http://www.doctrine-project.org>.
*/ */
namespace Doctrine\ORM\Tools\Cli\Tasks; namespace Doctrine\Common\Cli\Tasks;
use Doctrine\Common\Cli\Printers\AbstractPrinter, use Doctrine\Common\Cli\AbstractNamespace,
Doctrine\Common\Cli\TaskDocumentation, Doctrine\Common\Cli\TaskDocumentation;
Doctrine\Common\Cli\OptionGroup,
Doctrine\Common\Cli\Option;
/** /**
* Base class for CLI Tasks. * Base class for CLI Tasks.
* Provides basic methods and requires implementation of methods that * Provides basic methods and requires implementation of methods that
* each task should implement in order to correctly work. * each task should implement in order to correctly work.
* *
* The following arguments are common to all tasks:
*
* Argument: --config=<path>
* Description: Specifies the path to the configuration file to use. The configuration file
* can bootstrap an EntityManager as well as provide defaults for any cli
* arguments.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org * @link www.doctrine-project.org
* @since 2.0 * @since 2.0
* @version $Revision$ * @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com> * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com> * @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
...@@ -49,7 +41,7 @@ use Doctrine\Common\Cli\Printers\AbstractPrinter, ...@@ -49,7 +41,7 @@ use Doctrine\Common\Cli\Printers\AbstractPrinter,
abstract class AbstractTask abstract class AbstractTask
{ {
/** /**
* @var AbstractPrinter CLI Output Printer * @var AbstractNamespace CLI Namespace
*/ */
protected $_printer; protected $_printer;
...@@ -59,119 +51,86 @@ abstract class AbstractTask ...@@ -59,119 +51,86 @@ abstract class AbstractTask
protected $_documentation; protected $_documentation;
/** /**
* @var array CLI argument options * @var array CLI Task arguments
*/
protected $_arguments;
/**
* @var array Available CLI tasks
*/ */
protected $_availableTasks; protected $_arguments = array();
/**
* @var EntityManager The EntityManager instance
*/
protected $_em;
/** /**
* Constructor of CLI Task * Constructor of CLI Task
* *
* @param AbstractPrinter CLI Output Printer * @param AbstractNamespace CLI Namespace
*/ */
public function __construct(AbstractPrinter $printer) public function __construct(AbstractNamespace $namespace)
{ {
$this->_printer = $printer; $this->_namespace = $namespace;
$this->_documentation = new TaskDocumentation($printer); $this->_documentation = new TaskDocumentation($namespace);
// Include configuration option
$configGroup = new OptionGroup(OptionGroup::CARDINALITY_0_1);
$configGroup->addOption(
new Option('config', '<FILE_PATH>', 'Configuration file for EntityManager.')
);
$this->_documentation->addOption($configGroup);
// Complete the CLI Task Documentation creation // Complete the CLI Task Documentation creation
$this->buildDocumentation(); $this->buildDocumentation();
} }
/** /**
* Retrieves currently used CLI Output Printer * Retrieves the CLI Namespace
* *
* @return AbstractPrinter * @return AbstractNamespace
*/ */
public function getPrinter() public function getNamespace()
{ {
return $this->_printer; return $this->_namespace;
} }
/** /**
* Defines the CLI arguments * Retrieves the CLI Task Documentation
* *
* @param array CLI argument options * @return TaskDocumentation
*/ */
public function setArguments($arguments) public function getDocumentation()
{ {
$this->_arguments = $arguments; return $this->_documentation;
} }
/** /**
* Retrieves current CLI arguments * Defines the CLI Task arguments
* *
* @return array * @param array $arguments CLI Task arguments
*/
public function getArguments()
{
return $this->_arguments;
}
/**
* Defines the available CLI tasks
* *
* @param array Available CLI tasks * @return AbstractTask
*/ */
public function setAvailableTasks($availableTasks) public function setArguments(array $arguments = array())
{ {
$this->_availableTasks = $availableTasks; $this->_arguments = $arguments;
}
/** return $this;
* Retrieves the available CLI tasks
*
* @return array
*/
public function getAvailableTasks()
{
return $this->_availableTasks;
} }
/** /**
* Defines the EntityManager * Retrieves the CLI Task arguments
* *
* @param EntityManager The EntityManager instance * @return array
*/ */
public function setEntityManager($em) public function getArguments()
{ {
$this->_em = $em; return $this->_arguments;
} }
/** /**
* Retrieves current EntityManager * Retrieves currently used CLI Output Printer
* *
* @return EntityManager * @return AbstractPrinter
*/ */
public function getEntityManager() public function getPrinter()
{ {
return $this->_em; return $this->_namespace->getPrinter();
} }
/** /**
* Retrieves the CLI Task Documentation * Retrieves current used CLI Configuration
* *
* @return TaskDocumentation * @return Configuration
*/ */
public function getDocumentation() public function getConfiguration()
{ {
return $this->_documentation; return $this->_namespace->getConfiguration();
} }
/** /**
...@@ -186,7 +145,7 @@ abstract class AbstractTask ...@@ -186,7 +145,7 @@ abstract class AbstractTask
*/ */
public function extendedHelp() public function extendedHelp()
{ {
$this->_printer->output($this->_documentation->getCompleteDocumentation()); $this->getPrinter()->output($this->_documentation->getCompleteDocumentation());
} }
/** /**
...@@ -207,7 +166,7 @@ abstract class AbstractTask ...@@ -207,7 +166,7 @@ abstract class AbstractTask
*/ */
public function basicHelp() public function basicHelp()
{ {
$this->_printer $this->getPrinter()
->output($this->_documentation->getSynopsis()) ->output($this->_documentation->getSynopsis())
->output(PHP_EOL) ->output(PHP_EOL)
->output(' ' . $this->_documentation->getDescription()) ->output(' ' . $this->_documentation->getDescription())
...@@ -221,7 +180,11 @@ abstract class AbstractTask ...@@ -221,7 +180,11 @@ abstract class AbstractTask
* *
* @return boolean * @return boolean
*/ */
abstract public function validate(); public function validate()
{
// TODO implement DAG here!
return true;
}
/** /**
* Safely execution of task. * Safely execution of task.
......
...@@ -19,9 +19,9 @@ ...@@ -19,9 +19,9 @@
* <http://www.doctrine-project.org>. * <http://www.doctrine-project.org>.
*/ */
namespace Doctrine\ORM\Tools\Cli\Tasks; namespace Doctrine\Common\Cli\Tasks;
use Doctrine\Common\Util\Inflector; use Doctrine\Common\Cli\CliException;
/** /**
* CLI Task to display available commands help * CLI Task to display available commands help
...@@ -30,6 +30,7 @@ use Doctrine\Common\Util\Inflector; ...@@ -30,6 +30,7 @@ use Doctrine\Common\Util\Inflector;
* @link www.doctrine-project.org * @link www.doctrine-project.org
* @since 2.0 * @since 2.0
* @version $Revision$ * @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com> * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com> * @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
...@@ -60,38 +61,25 @@ class HelpTask extends AbstractTask ...@@ -60,38 +61,25 @@ class HelpTask extends AbstractTask
$this->run(); $this->run();
} }
/**
* @inheritdoc
*/
public function validate()
{
return true;
}
/** /**
* Exposes the available tasks * Exposes the available tasks
* *
*/ */
public function run() public function run()
{ {
$this->getPrinter()->writeln('Available Tasks:', 'NONE'); $this->getPrinter()->writeln('Available Tasks:', 'HEADER')->write(PHP_EOL);
// Switch between ALL available tasks and display the basic Help of each one // Find the CLI Controller
$availableTasks = $this->getAvailableTasks(); $cliController = $this->getNamespace()->getParentNamespace();
$helpTaskName = Inflector::classify(str_replace('-', '_', 'help')); // Switch between ALL available tasks and display the basic Help of each one
unset($availableTasks[$helpTaskName]); $availableTasks = $cliController->getAvailableTasks();
unset($availableTasks['Core:Help']);
ksort($availableTasks); ksort($availableTasks);
foreach ($availableTasks as $taskName => $taskClass) { foreach (array_keys($availableTasks) as $taskName) {
$task = new $taskClass($this->getPrinter()); $cliController->runTask($taskName, array('basic-help' => true));
$task->setAvailableTasks($availableTasks);
$task->setEntityManager($this->getEntityManager());
$task->setArguments($this->getArguments());
$task->basicHelp();
} }
} }
} }
\ No newline at end of file
...@@ -56,19 +56,7 @@ class Inflector ...@@ -56,19 +56,7 @@ class Inflector
*/ */
public static function classify($word) public static function classify($word)
{ {
$word = preg_replace('/[$]/', '', $word); return str_replace(" ", "", ucwords(strtr($word, "_-", " ")));
return preg_replace_callback('~(_?)(_)([\w])~', array(__CLASS__, "classifyCallback"), ucfirst(strtolower($word)));
}
/**
* Callback function to classify a classname properly.
*
* @param array $matches An array of matches from a pcre_replace call
* @return string $string A string with matches 1 and mathces 3 in upper case.
*/
public static function classifyCallback($matches)
{
return $matches[1] . strtoupper($matches[3]);
} }
/** /**
......
...@@ -19,9 +19,10 @@ ...@@ -19,9 +19,10 @@
* <http://www.doctrine-project.org>. * <http://www.doctrine-project.org>.
*/ */
namespace Doctrine\ORM\Tools\Cli\Tasks; namespace Doctrine\DBAL\Tools\Cli\Tasks;
use Doctrine\Common\DoctrineException, use Doctrine\Common\Cli\Tasks\AbstractTask,
Doctrine\Common\Cli\CliException,
Doctrine\Common\Util\Debug, Doctrine\Common\Util\Debug,
Doctrine\Common\Cli\Option, Doctrine\Common\Cli\Option,
Doctrine\Common\Cli\OptionGroup; Doctrine\Common\Cli\OptionGroup;
...@@ -47,13 +48,11 @@ class RunSqlTask extends AbstractTask ...@@ -47,13 +48,11 @@ class RunSqlTask extends AbstractTask
{ {
$dqlAndFile = new OptionGroup(OptionGroup::CARDINALITY_1_1, array( $dqlAndFile = new OptionGroup(OptionGroup::CARDINALITY_1_1, array(
new Option( new Option(
'sql', '<DQL>', 'sql', '<SQL>', 'The SQL to execute.' . PHP_EOL .
'The SQL to execute.' . PHP_EOL .
'If defined, --file can not be requested on same task.' 'If defined, --file can not be requested on same task.'
), ),
new Option( new Option(
'file', '<FILE_PATH>', 'file', '<PATH>', 'The path to the file with the SQL to execute.' . PHP_EOL .
'The path to the file with the SQL to execute.' . PHP_EOL .
'If defined, --sql can not be requested on same task.' 'If defined, --sql can not be requested on same task.'
) )
)); ));
...@@ -75,15 +74,17 @@ class RunSqlTask extends AbstractTask ...@@ -75,15 +74,17 @@ class RunSqlTask extends AbstractTask
*/ */
public function validate() public function validate()
{ {
$args = $this->getArguments(); $arguments = $this->getArguments();
$printer = $this->getPrinter(); $em = $this->getConfiguration()->getAttribute('em');
$isSql = isset($args['sql']); if ($em === null) {
$isFile = isset($args['file']); throw new CliException(
"Attribute 'em' of CLI Configuration is not defined or it is not a valid EntityManager."
);
}
if ( ! ($isSql ^ $isFile)) { if ( ! (isset($arguments['sql']) ^ isset($arguments['file']))) {
$printer->writeln("One of --sql or --file required, and only one.", 'ERROR'); throw new CliException('One of --sql or --file required, and only one.');
return false;
} }
return true; return true;
...@@ -95,27 +96,23 @@ class RunSqlTask extends AbstractTask ...@@ -95,27 +96,23 @@ class RunSqlTask extends AbstractTask
*/ */
public function run() public function run()
{ {
$args = $this->getArguments(); $arguments = $this->getArguments();
try { if (isset($arguments['file'])) {
if (isset($args['file'])) {
//TODO //TODO
} else if (isset($args['sql'])) { } else if (isset($arguments['sql'])) {
$conn = $this->getEntityManager()->getConnection(); $em = $this->getConfiguration()->getAttribute('em');
if (preg_match('/^select/i', $args['sql'])) { if (preg_match('/^select/i', $arguments['sql'])) {
$stmt = $conn->execute($args['sql']); $stmt = $em->getConnection()->execute($arguments['sql']);
$resultSet = $stmt->fetchAll(\Doctrine\DBAL\Connection::FETCH_ASSOC); $resultSet = $stmt->fetchAll(\Doctrine\DBAL\Connection::FETCH_ASSOC);
} else { } else {
$resultSet = $conn->executeUpdate($args['sql']); $resultSet = $em->getConnection()->executeUpdate($arguments['sql']);
} }
$maxDepth = isset($args['depth']) ? $args['depth'] : 7; $maxDepth = isset($args['arguments']) ? $arguments['depth'] : 7;
Debug::dump($resultSet, $maxDepth); Debug::dump($resultSet, $maxDepth);
} }
} catch (\Exception $ex) {
throw new DoctrineException($ex);
}
} }
} }
\ No newline at end of file
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
namespace Doctrine\ORM\Tools\Cli\Tasks; namespace Doctrine\ORM\Tools\Cli\Tasks;
use Doctrine\Common\DoctrineException, use Doctrine\Common\Cli\Tasks\AbstractTask,
Doctrine\Common\Util\Debug, Doctrine\Common\Cli\CliException,
Doctrine\Common\Cli\Option, Doctrine\Common\Cli\Option,
Doctrine\Common\Cli\OptionGroup, Doctrine\Common\Cli\OptionGroup,
Doctrine\Common\Cache\AbstractDriver; Doctrine\Common\Cache\AbstractDriver;
...@@ -56,7 +56,7 @@ class ClearCacheTask extends AbstractTask ...@@ -56,7 +56,7 @@ class ClearCacheTask extends AbstractTask
new Option('id', '<ID>', 'The id of the cache entry to delete (accepts * wildcards).'), new Option('id', '<ID>', 'The id of the cache entry to delete (accepts * wildcards).'),
new Option('regex', '<REGEX>', 'Delete cache entries that match the given regular expression.'), new Option('regex', '<REGEX>', 'Delete cache entries that match the given regular expression.'),
new Option('prefix', '<PREFIX>', 'Delete cache entries that have the given prefix.'), new Option('prefix', '<PREFIX>', 'Delete cache entries that have the given prefix.'),
new Option('suffic', '<SUFFIX>', 'Delete cache entries that have the given suffix.') new Option('suffix', '<SUFFIX>', 'Delete cache entries that have the given suffix.')
)) ))
)) ))
)); ));
...@@ -68,43 +68,52 @@ class ClearCacheTask extends AbstractTask ...@@ -68,43 +68,52 @@ class ClearCacheTask extends AbstractTask
->addOption($cacheOptions); ->addOption($cacheOptions);
} }
/**
* @inheritdoc
*/
public function validate() public function validate()
{ {
$printer = $this->getPrinter(); $arguments = $this->getArguments();
$args = $this->getArguments();
// Check if we have an active EntityManager
$em = $this->getConfiguration()->getAttribute('em');
if ($em === null) {
throw new CliException(
"Attribute 'em' of CLI Configuration is not defined or it is not a valid EntityManager."
);
}
// When clearing the query cache no need to specify // When clearing the query cache no need to specify
// id, regex, prefix or suffix. // id, regex, prefix or suffix.
if ((isset($args['query']) || isset($args['metadata'])) if (
&& (isset($args['id']) (isset($arguments['query']) || isset($arguments['metadata'])) && (isset($arguments['id']) ||
|| isset($args['regex']) isset($args['regex']) || isset($args['prefix']) || isset($args['suffix']))
|| isset($args['prefix']) ) {
|| isset($args['suffix']))) { throw new CliException(
$printer->writeln(
'When clearing the query or metadata cache do not ' . 'When clearing the query or metadata cache do not ' .
'specify any --id, --regex, --prefix or --suffix.', 'specify any --id, --regex, --prefix or --suffix.'
'ERROR'
); );
return false;
} }
return true; return true;
} }
/**
* @inheritdoc
*/
public function run() public function run()
{ {
$arguments = $this->getArguments();
$printer = $this->getPrinter(); $printer = $this->getPrinter();
$args = $this->getArguments();
$query = isset($args['query']); $query = isset($arguments['query']);
$result = isset($args['result']); $result = isset($arguments['result']);
$metadata = isset($args['metadata']); $metadata = isset($arguments['metadata']);
$id = isset($args['id']) ? $args['id'] : null; $id = isset($arguments['id']) ? $arguments['id'] : null;
$regex = isset($args['regex']) ? $args['regex'] : null; $regex = isset($arguments['regex']) ? $arguments['regex'] : null;
$prefix = isset($args['prefix']) ? $args['prefix'] : null; $prefix = isset($arguments['prefix']) ? $arguments['prefix'] : null;
$suffix = isset($args['suffix']) ? $args['suffix'] : null; $suffix = isset($arguments['suffix']) ? $arguments['suffix'] : null;
$all = false; $all = false;
...@@ -112,38 +121,24 @@ class ClearCacheTask extends AbstractTask ...@@ -112,38 +121,24 @@ class ClearCacheTask extends AbstractTask
$all = true; $all = true;
} }
$configuration = $this->getEntityManager()->getConfiguration(); $em = $this->getConfiguration()->getAttribute('em');
$configuration = $em->getConfiguration();
if ($query || $all) { if ($query || $all) {
$this->_doDelete( $this->_doDelete(
'query', 'query', $configuration->getQueryCacheImpl(), $id, $regex, $prefix, $suffix
$configuration->getQueryCacheImpl(),
$id,
$regex,
$prefix,
$suffix
); );
} }
if ($result || $all) { if ($result || $all) {
$this->_doDelete( $this->_doDelete(
'result', 'result', $configuration->getResultCacheImpl(), $id, $regex, $prefix, $suffix
$configuration->getResultCacheImpl(),
$id,
$regex,
$prefix,
$suffix
); );
} }
if ($metadata || $all) { if ($metadata || $all) {
$this->_doDelete( $this->_doDelete(
'metadata', 'metadata', $configuration->getMetadataCacheImpl(), $id, $regex, $prefix, $suffix
$configuration->getMetadataCacheImpl(),
$id,
$regex,
$prefix,
$suffix
); );
} }
} }
...@@ -153,54 +148,56 @@ class ClearCacheTask extends AbstractTask ...@@ -153,54 +148,56 @@ class ClearCacheTask extends AbstractTask
$printer = $this->getPrinter(); $printer = $this->getPrinter();
if ( ! $cacheDriver) { if ( ! $cacheDriver) {
$printer->writeln('No driver has been configured for the ' . $type . ' cache.', 'ERROR'); throw new CliException('No driver has been configured for the ' . $type . ' cache.');
return false;
} }
if ($id) { if ($id) {
$printer->writeln('Clearing ' . $type . ' cache entries that match the id "' . $id . '"', 'INFO'); $printer->writeln('Clearing ' . $type . ' cache entries that match the id "' . $id . '".', 'INFO');
$deleted = $cacheDriver->delete($id); $deleted = $cacheDriver->delete($id);
if (is_array($deleted)) { if (is_array($deleted)) {
$this->_printDeleted($printer, $type, $deleted); $this->_printDeleted($type, $deleted);
} else if (is_bool($deleted) && $deleted) { } else if (is_bool($deleted) && $deleted) {
$this->_printDeleted($printer, $type, array($id)); $this->_printDeleted($type, array($id));
} }
} }
if ($regex) { if ($regex) {
$printer->writeln('Clearing ' . $type . ' cache entries that match the regular expression "' . $regex . '"', 'INFO'); $printer->writeln('Clearing ' . $type . ' cache entries that match the regular expression ".' . $regex . '"', 'INFO');
$this->_printDeleted($printer, $type, $cacheDriver->deleteByRegex('/' . $regex. '/')); $this->_printDeleted($type, $cacheDriver->deleteByRegex('/' . $regex. '/'));
} }
if ($prefix) { if ($prefix) {
$printer->writeln('Clearing ' . $type . ' cache entries that have the prefix "' . $prefix . '"', 'INFO'); $printer->writeln('Clearing ' . $type . ' cache entries that have the prefix "' . $prefix . '".', 'INFO');
$this->_printDeleted($printer, $type, $cacheDriver->deleteByPrefix($prefix)); $this->_printDeleted($type, $cacheDriver->deleteByPrefix($prefix));
} }
if ($suffix) { if ($suffix) {
$printer->writeln('Clearing ' . $type . ' cache entries that have the suffix "' . $suffix . '"', 'INFO'); $printer->writeln('Clearing ' . $type . ' cache entries that have the suffix "' . $suffix . '".', 'INFO');
$this->_printDeleted($printer, $type, $cacheDriver->deleteBySuffix($suffix)); $this->_printDeleted($type, $cacheDriver->deleteBySuffix($suffix));
} }
if ( ! $id && ! $regex && ! $prefix && ! $suffix) { if ( ! $id && ! $regex && ! $prefix && ! $suffix) {
$printer->writeln('Clearing all ' . $type . ' cache entries', 'INFO'); $printer->writeln('Clearing all ' . $type . ' cache entries.', 'INFO');
$this->_printDeleted($printer, $type, $cacheDriver->deleteAll()); $this->_printDeleted($type, $cacheDriver->deleteAll());
} }
} }
private function _printDeleted($printer, $type, array $ids) private function _printDeleted($type, array $ids)
{ {
$printer = $this->getPrinter();
if ( ! empty($ids)) { if ( ! empty($ids)) {
foreach ($ids as $id) { foreach ($ids as $id) {
$printer->writeln(' - ' . $id); $printer->writeln(' - ' . $id);
} }
} else { } else {
$printer->writeln('No ' . $type . ' cache entries found', 'ERROR'); throw new CliException('No ' . $type . ' cache entries found.');
} }
$printer->write(PHP_EOL); $printer->write(PHP_EOL);
......
...@@ -21,7 +21,8 @@ ...@@ -21,7 +21,8 @@
namespace Doctrine\ORM\Tools\Cli\Tasks; namespace Doctrine\ORM\Tools\Cli\Tasks;
use Doctrine\Common\DoctrineException, use Doctrine\Common\Cli\Tasks\AbstractTask,
Doctrine\Common\Cli\CliException,
Doctrine\Common\Cli\Option, Doctrine\Common\Cli\Option,
Doctrine\Common\Cli\OptionGroup, Doctrine\Common\Cli\OptionGroup,
Doctrine\ORM\Tools\Export\ClassMetadataExporter; Doctrine\ORM\Tools\Export\ClassMetadataExporter;
...@@ -65,48 +66,65 @@ class ConvertMappingTask extends AbstractTask ...@@ -65,48 +66,65 @@ class ConvertMappingTask extends AbstractTask
*/ */
public function validate() public function validate()
{ {
$args = $this->getArguments(); $arguments = $this->getArguments();
$printer = $this->getPrinter();
if (isset($arguments['from-database']) && $arguments['from-database']) {
$arguments['from'] = 'database';
if (array_key_exists('from-database', $args)) { $this->setArguments($arguments);
$args['from'][0] = 'database';
$this->setArguments($args);
} }
if (!(isset($args['from']) && isset($args['to']) && isset($args['dest']))) { if (!(isset($arguments['from']) && isset($arguments['to']) && isset($arguments['dest']))) {
$printer->writeln('You must include a value for all three options: --from, --to and --dest', 'ERROR'); throw new CliException(
return false; 'You must include a value for all three options: --from, --to and --dest.'
);
} }
if ($args['to'] != 'annotation' && isset($args['extend'])) {
$printer->writeln('You can only use the --extend argument when converting to annoations.', 'ERROR'); if (strtolower($arguments['to']) != 'annotation' && isset($arguments['extend'])) {
return false; throw new CliException(
'You can only use the --extend argument when converting to annotations.'
);
} }
if ($args['from'][0] == 'database') {
$em = $this->getEntityManager(); if (strtolower($arguments['from']) == 'database') {
// Check if we have an active EntityManager
$em = $this->getConfiguration()->getAttribute('em');
if ($em === null) {
throw new CliException(
"Attribute 'em' of CLI Configuration is not defined or it is not a valid EntityManager."
);
}
$config = $em->getConfiguration(); $config = $em->getConfiguration();
$config->setMetadataDriverImpl(new \Doctrine\ORM\Mapping\Driver\DatabaseDriver($em->getConnection()->getSchemaManager())); $config->setMetadataDriverImpl(
new \Doctrine\ORM\Mapping\Driver\DatabaseDriver(
$em->getConnection()->getSchemaManager()
)
);
} }
return true; return true;
} }
public function run() public function run()
{ {
$printer = $this->getPrinter(); $arguments = $this->getArguments();
$args = $this->getArguments();
$cme = new ClassMetadataExporter(); $cme = new ClassMetadataExporter();
$printer = $this->getPrinter();
// Get exporter and configure it // Get exporter and configure it
$exporter = $cme->getExporter($args['to'], $args['dest']); $exporter = $cme->getExporter($arguments['to'], $arguments['dest']);
if (isset($args['extend'])) { if (isset($arguments['extend']) && $arguments['extend']) {
$exporter->setClassToExtend($args['extend']); $exporter->setClassToExtend($arguments['extend']);
} }
if (isset($args['num-spaces'])) {
$exporter->setNumSpaces($args['num-spaces']); if (isset($arguments['num-spaces']) && $arguments['extend']) {
$exporter->setNumSpaces($arguments['num-spaces']);
} }
$from = (array) $args['from']; $from = (array) $arguments['from'];
if ($this->_isDoctrine1Schema($from)) { if ($this->_isDoctrine1Schema($from)) {
$printer->writeln('Converting Doctrine 1 schema to Doctrine 2 mapping files', 'INFO'); $printer->writeln('Converting Doctrine 1 schema to Doctrine 2 mapping files', 'INFO');
...@@ -116,40 +134,38 @@ class ConvertMappingTask extends AbstractTask ...@@ -116,40 +134,38 @@ class ConvertMappingTask extends AbstractTask
} else { } else {
foreach ($from as $source) { foreach ($from as $source) {
$sourceArg = $source; $sourceArg = $source;
$type = $this->_determineSourceType($sourceArg); $type = $this->_determineSourceType($sourceArg);
if ( ! $type) { if ( ! $type) {
throw DoctrineException::invalidMappingSourceType($sourceArg); throw DoctrineException::invalidMappingSourceType($sourceArg);
} }
$source = $this->_getSourceByType($type, $sourceArg); $source = $this->_getSourceByType($type, $sourceArg);
$printer->writeln( $printer->writeln(
sprintf( sprintf(
'Adding "%s" mapping source which contains the "%s" format', 'Adding "%s" mapping source which contains the "%s" format',
$printer->format($sourceArg, 'KEYWORD'), $printer->format($sourceArg, 'KEYWORD'), $printer->format($type, 'KEYWORD')
$printer->format($type, 'KEYWORD')
) )
); );
$cme->addMappingSource($source, $type); $cme->addMappingSource($source, $type);
} }
$metadatas = $cme->getMetadatasForMappingSources(); $metadatas = $cme->getMetadatasForMappingSources();
} }
foreach ($metadatas as $metadata) { foreach ($metadatas as $metadata) {
$printer->writeln( $printer->writeln(
sprintf( sprintf('Processing entity "%s"', $printer->format($metadata->name, 'KEYWORD'))
'Processing entity "%s"',
$printer->format($metadata->name, 'KEYWORD')
)
); );
} }
$printer->writeln( $printer->writeln(
sprintf( sprintf(
'Exporting "%s" mapping information to directory "%s"', 'Exporting "%s" mapping information to directory "%s"',
$printer->format($args['to'], 'KEYWORD'), $printer->format($arguments['to'], 'KEYWORD'),
$printer->format($args['dest'], 'KEYWORD') $printer->format($arguments['dest'], 'KEYWORD')
) )
); );
...@@ -167,9 +183,11 @@ class ConvertMappingTask extends AbstractTask ...@@ -167,9 +183,11 @@ class ConvertMappingTask extends AbstractTask
} }
$files = glob(current($from) . '/*.yml'); $files = glob(current($from) . '/*.yml');
if ($files) { if ($files) {
$array = \sfYaml::load($files[0]); $array = \sfYaml::load($files[0]);
$first = current($array); $first = current($array);
// We're dealing with a Doctrine 1 schema if you have // We're dealing with a Doctrine 1 schema if you have
// a columns index in the first model array // a columns index in the first model array
return isset($first['columns']); return isset($first['columns']);
...@@ -185,6 +203,7 @@ class ConvertMappingTask extends AbstractTask ...@@ -185,6 +203,7 @@ class ConvertMappingTask extends AbstractTask
if (is_dir($source)) { if (is_dir($source)) {
// Find the files in the directory // Find the files in the directory
$files = glob($source . '/*.*'); $files = glob($source . '/*.*');
if ( ! $files) { if ( ! $files) {
throw new \InvalidArgumentException( throw new \InvalidArgumentException(
sprintf('No mapping files found in "%s"', $source) sprintf('No mapping files found in "%s"', $source)
...@@ -201,6 +220,7 @@ class ConvertMappingTask extends AbstractTask ...@@ -201,6 +220,7 @@ class ConvertMappingTask extends AbstractTask
// first file in the directory (yml, xml, etc) // first file in the directory (yml, xml, etc)
} else { } else {
$info = pathinfo($files[0]); $info = pathinfo($files[0]);
return $info['extension']; return $info['extension'];
} }
// Nothing special for database // Nothing special for database
...@@ -214,7 +234,9 @@ class ConvertMappingTask extends AbstractTask ...@@ -214,7 +234,9 @@ class ConvertMappingTask extends AbstractTask
// If --from==database then the source is an instance of SchemaManager // If --from==database then the source is an instance of SchemaManager
// for the current EntityMAnager // for the current EntityMAnager
if ($type == 'database') { if ($type == 'database') {
return $this->_em->getConnection()->getSchemaManager(); $em = $this->getConfiguration->getAttribute('em');
return $em->getConnection()->getSchemaManager();
} else { } else {
return $source; return $source;
} }
......
...@@ -21,7 +21,8 @@ ...@@ -21,7 +21,8 @@
namespace Doctrine\ORM\Tools\Cli\Tasks; namespace Doctrine\ORM\Tools\Cli\Tasks;
use Doctrine\Common\Cache\AbstractDriver; use Doctrine\Common\Cli\Tasks\AbstractTask,
Doctrine\Common\Cli\CliException;
/** /**
* CLI Task to ensure that Doctrine is properly configured for a production environment. * CLI Task to ensure that Doctrine is properly configured for a production environment.
...@@ -30,6 +31,7 @@ use Doctrine\Common\Cache\AbstractDriver; ...@@ -30,6 +31,7 @@ use Doctrine\Common\Cache\AbstractDriver;
* @link www.doctrine-project.org * @link www.doctrine-project.org
* @since 2.0 * @since 2.0
* @version $Revision$ * @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com> * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com> * @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
...@@ -51,17 +53,24 @@ class EnsureProductionSettingsTask extends AbstractTask ...@@ -51,17 +53,24 @@ class EnsureProductionSettingsTask extends AbstractTask
*/ */
public function validate() public function validate()
{ {
// Check if we have an active EntityManager
$em = $this->getConfiguration()->getAttribute('em');
if ($em === null) {
throw new CliException(
"Attribute 'em' of CLI Configuration is not defined or it is not a valid EntityManager."
);
}
return true; return true;
} }
/**
* @inheritdoc
*/
public function run() public function run()
{ {
$printer = $this->getPrinter(); $em = $this->getConfiguration()->getAttribute('em');
$em->getConfiguration()->ensureProductionSettings();
try {
$this->getEntityManager()->getConfiguration()->ensureProductionSettings();
} catch (\Doctrine\Common\DoctrineException $e) {
$printer->writeln($e->getMessage(), 'ERROR');
}
} }
} }
\ No newline at end of file
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
namespace Doctrine\ORM\Tools\Cli\Tasks; namespace Doctrine\ORM\Tools\Cli\Tasks;
use Doctrine\Common\DoctrineException, use Doctrine\Common\Cli\Tasks\AbstractTask,
Doctrine\Common\Cli\CliException,
Doctrine\Common\Cli\Option, Doctrine\Common\Cli\Option,
Doctrine\Common\Cli\OptionGroup; Doctrine\Common\Cli\OptionGroup;
...@@ -24,6 +25,10 @@ class GenerateProxiesTask extends AbstractTask ...@@ -24,6 +25,10 @@ class GenerateProxiesTask extends AbstractTask
*/ */
public function buildDocumentation() public function buildDocumentation()
{ {
$classDir = new OptionGroup(OptionGroup::CARDINALITY_1_1, array(
new Option('class-dir', '<PATH>', 'Specified directory where mapping classes are located.')
));
$toDir = new OptionGroup(OptionGroup::CARDINALITY_0_1, array( $toDir = new OptionGroup(OptionGroup::CARDINALITY_0_1, array(
new Option('to-dir', '<PATH>', 'Generates the classes in the specified directory.') new Option('to-dir', '<PATH>', 'Generates the classes in the specified directory.')
)); ));
...@@ -32,6 +37,7 @@ class GenerateProxiesTask extends AbstractTask ...@@ -32,6 +37,7 @@ class GenerateProxiesTask extends AbstractTask
$doc->setName('generate-proxies') $doc->setName('generate-proxies')
->setDescription('Generates proxy classes for entity classes.') ->setDescription('Generates proxy classes for entity classes.')
->getOptionGroup() ->getOptionGroup()
->addOption($classDir)
->addOption($toDir); ->addOption($toDir);
} }
...@@ -40,18 +46,25 @@ class GenerateProxiesTask extends AbstractTask ...@@ -40,18 +46,25 @@ class GenerateProxiesTask extends AbstractTask
*/ */
public function validate() public function validate()
{ {
$args = $this->getArguments(); $arguments = $this->getArguments();
$printer = $this->getPrinter(); $em = $this->getConfiguration()->getAttribute('em');
if ($em === null) {
throw new CliException(
"Attribute 'em' of CLI Configuration is not defined or it is not a valid EntityManager."
);
}
$metadataDriver = $this->getEntityManager()->getConfiguration()->getMetadataDriverImpl(); $metadataDriver = $em->getConfiguration()->getMetadataDriverImpl();
if ($metadataDriver instanceof \Doctrine\ORM\Mapping\Driver\AnnotationDriver) { if ($metadataDriver instanceof \Doctrine\ORM\Mapping\Driver\AnnotationDriver) {
if ( ! isset($args['class-dir'])) { if (isset($arguments['class-dir'])) {
$printer->writeln("The supplied configuration uses the annotation metadata driver."
. " The 'class-dir' argument is required for this driver.", 'ERROR');
return false;
} else {
$metadataDriver->setClassDirectory($args['class-dir']); $metadataDriver->setClassDirectory($args['class-dir']);
} else {
throw new CliException(
'The supplied configuration uses the annotation metadata driver. ' .
"The 'class-dir' argument is required for this driver."
);
} }
} }
...@@ -59,30 +72,29 @@ class GenerateProxiesTask extends AbstractTask ...@@ -59,30 +72,29 @@ class GenerateProxiesTask extends AbstractTask
} }
/** /**
* Executes the task. * @inheritdoc
*/ */
public function run() public function run()
{ {
$args = $this->getArguments(); $arguments = $this->getArguments();
$printer = $this->getPrinter();
$em = $this->getEntityManager(); $em = $this->getConfiguration->getAttribute('em');
$cmf = $em->getMetadataFactory(); $cmf = $em->getMetadataFactory();
$classes = $cmf->getAllMetadata(); $classes = $cmf->getAllMetadata();
$printer = $this->getPrinter();
$factory = $em->getProxyFactory(); $factory = $em->getProxyFactory();
if (empty($classes)) { if (empty($classes)) {
$printer->writeln('No classes to process.', 'INFO'); $printer->writeln('No classes to process.', 'INFO');
return; } else {
} $factory->generateProxyClasses(
$classes, isset($arguments['to-dir']) ? $arguments['to-dir'] : null
$factory->generateProxyClasses($classes, isset($args['to-dir']) ? $args['to-dir'] : null); );
$printer->writeln( $printer->writeln(
'Proxy classes generated to: ' . 'Proxy classes generated to: ' . (isset($arguments['to-dir'])
(isset($args['to-dir']) ? $args['to-dir'] : $em->getConfiguration()->getProxyDir()) ? $arguments['to-dir'] : $em->getConfiguration()->getProxyDir())
); );
} }
}
} }
\ No newline at end of file
...@@ -21,7 +21,8 @@ ...@@ -21,7 +21,8 @@
namespace Doctrine\ORM\Tools\Cli\Tasks; namespace Doctrine\ORM\Tools\Cli\Tasks;
use Doctrine\Common\DoctrineException, use Doctrine\Common\Cli\Tasks\AbstractTask,
Doctrine\Common\Cli\CliException,
Doctrine\Common\Util\Debug, Doctrine\Common\Util\Debug,
Doctrine\Common\Cli\Option, Doctrine\Common\Cli\Option,
Doctrine\Common\Cli\OptionGroup; Doctrine\Common\Cli\OptionGroup;
...@@ -65,12 +66,17 @@ class RunDqlTask extends AbstractTask ...@@ -65,12 +66,17 @@ class RunDqlTask extends AbstractTask
*/ */
public function validate() public function validate()
{ {
$args = $this->getArguments(); $arguments = $this->getArguments();
$printer = $this->getPrinter(); $em = $this->getConfiguration()->getAttribute('em');
if ( ! isset($args['dql'])) { if ($em === null) {
$printer->writeln("Argument --dql must be defined.", 'ERROR'); throw new CliException(
return false; "Attribute 'em' of CLI Configuration is not defined or it is not a valid EntityManager."
);
}
if ( ! isset($arguments['dql'])) {
throw new CliException('Argument --dql must be defined.');
} }
return true; return true;
...@@ -78,21 +84,16 @@ class RunDqlTask extends AbstractTask ...@@ -78,21 +84,16 @@ class RunDqlTask extends AbstractTask
/** /**
* Executes the task. * @inheritdoc
*/ */
public function run() public function run()
{ {
$args = $this->getArguments(); $arguments = $this->getArguments();
$em = $this->getConfiguration()->getAttribute('em');
try { $query = $em->createQuery($arguments['dql']);
$query = $this->getEntityManager()->createQuery($args['dql']);
$resultSet = $query->getResult(); $resultSet = $query->getResult();
$maxDepth = isset($arguments['depth']) ? $arguments['depth'] : 7;
$maxDepth = isset($args['depth']) ? $args['depth'] : 7;
Debug::dump($resultSet, $maxDepth); Debug::dump($resultSet, $maxDepth);
} catch (\Exception $ex) {
throw new DoctrineException($ex);
}
} }
} }
\ No newline at end of file
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
namespace Doctrine\ORM\Tools\Cli\Tasks; namespace Doctrine\ORM\Tools\Cli\Tasks;
use Doctrine\Common\DoctrineException, use Doctrine\Common\Cli\Tasks\AbstractTask,
Doctrine\Common\Cli\CliException,
Doctrine\Common\Cli\Option, Doctrine\Common\Cli\Option,
Doctrine\Common\Cli\OptionGroup, Doctrine\Common\Cli\OptionGroup,
Doctrine\ORM\Tools\SchemaTool, Doctrine\ORM\Tools\SchemaTool,
...@@ -100,44 +101,56 @@ class SchemaToolTask extends AbstractTask ...@@ -100,44 +101,56 @@ class SchemaToolTask extends AbstractTask
*/ */
public function validate() public function validate()
{ {
$args = $this->getArguments(); $arguments = $this->getArguments();
$printer = $this->getPrinter(); $em = $this->getConfiguration()->getAttribute('em');
if ($em === null) {
throw new CliException(
"Attribute 'em' of CLI Configuration is not defined or it is not a valid EntityManager."
);
}
if (array_key_exists('re-create', $args)) { if (isset($arguments['re-create'])) {
$args['drop'] = true; $arguments['drop'] = true;
$args['create'] = true; $arguments['create'] = true;
$this->setArguments($args);
unset($arguments['re-create']);
$this->setArguments($arguments);
} }
$isCreate = isset($args['create']); $isCreate = isset($arguments['create']) && $arguments['create'];
$isDrop = isset($args['drop']); $isDrop = isset($arguments['drop']) && $arguments['drop'];
$isUpdate = isset($args['update']); $isUpdate = isset($arguments['update']) && $arguments['update'];
$isCompleteUpdate = isset($args['complete-update']); $isCompleteUpdate = isset($arguments['complete-update']) && $arguments['complete-update'];
if ($isUpdate && ($isCreate || $isDrop || $isCompleteUpdate)) { if ($isUpdate && ($isCreate || $isDrop || $isCompleteUpdate)) {
$printer->writeln("You can't use --update with --create, --drop or --complete-update", 'ERROR'); throw new CliException(
return false; 'You cannot use --update with --create, --drop or --complete-update.'
);
} }
if ($isCompleteUpdate && ($isCreate || $isDrop || $isUpdate)) { if ($isCompleteUpdate && ($isCreate || $isDrop || $isUpdate)) {
$printer->writeln("You can't use --update with --create, --drop or --update", 'ERROR'); throw new CliException('You cannot use --update with --create, --drop or --update.');
return false;
} }
if ( ! ($isCreate || $isDrop || $isUpdate || $isCompleteUpdate)) { if ( ! ($isCreate || $isDrop || $isUpdate || $isCompleteUpdate)) {
$printer->writeln('You must specify at a minimum one of the options (--create, --drop, --update, --re-create, --complete-update).', 'ERROR'); throw new CliException(
return false; 'You must specify at a minimum one of the options ' .
'(--create, --drop, --update, --re-create or --complete-update).'
);
} }
$metadataDriver = $this->getEntityManager()->getConfiguration()->getMetadataDriverImpl(); $metadataDriver = $this->getEntityManager()->getConfiguration()->getMetadataDriverImpl();
if ($metadataDriver instanceof \Doctrine\ORM\Mapping\Driver\AnnotationDriver) { if ($metadataDriver instanceof \Doctrine\ORM\Mapping\Driver\AnnotationDriver) {
if ( ! isset($args['class-dir'])) { if (isset($args['class-dir'])) {
$printer->writeln("The supplied configuration uses the annotation metadata driver."
. " The 'class-dir' argument is required for this driver.", 'ERROR');
return false;
} else {
$metadataDriver->setClassDirectory($args['class-dir']); $metadataDriver->setClassDirectory($args['class-dir']);
} else {
throw new CliException(
'The supplied configuration uses the annotation metadata driver. ' .
"The 'class-dir' argument is required for this driver."
);
} }
} }
...@@ -145,80 +158,66 @@ class SchemaToolTask extends AbstractTask ...@@ -145,80 +158,66 @@ class SchemaToolTask extends AbstractTask
} }
/** /**
* Executes the task. * @inheritdoc
*/ */
public function run() public function run()
{ {
$args = $this->getArguments(); $arguments = $this->getArguments();
$printer = $this->getPrinter();
$isCreate = isset($args['create']); $isCreate = isset($arguments['create']) && $arguments['create'];
$isDrop = isset($args['drop']); $isDrop = isset($arguments['drop']) && $arguments['drop'];
$isUpdate = isset($args['update']); $isUpdate = isset($arguments['update']) && $arguments['update'];
$isCompleteUpdate = isset($args['complete-update']); $isCompleteUpdate = isset($arguments['complete-update']) && $arguments['complete-update'];
$em = $this->getEntityManager(); $em = $this->getConfiguration()->getAttribute('em');
$cmf = $em->getMetadataFactory();
$cmf = $em->getMetadataFactory();
$classes = $cmf->getAllMetadata(); $classes = $cmf->getAllMetadata();
$printer = $this->getPrinter();
if (empty($classes)) { if (empty($classes)) {
$printer->writeln('No classes to process.', 'INFO'); $printer->writeln('No classes to process.', 'INFO');
return; return;
} }
$tool = new SchemaTool($em); $tool = new SchemaTool($em);
if ($isDrop) { if ($isDrop) {
if (isset($args['dump-sql'])) { if (isset($arguments['dump-sql'])) {
foreach ($tool->getDropSchemaSql($classes) as $sql) { foreach ($tool->getDropSchemaSql($classes) as $sql) {
$printer->writeln($sql); $printer->writeln($sql);
} }
} else { } else {
$printer->writeln('Dropping database schema...', 'INFO'); $printer->writeln('Dropping database schema...', 'INFO');
try {
$tool->dropSchema($classes); $tool->dropSchema($classes);
$printer->writeln('Database schema dropped successfully.', 'INFO'); $printer->writeln('Database schema dropped successfully.', 'INFO');
} catch (\Exception $ex) {
throw new DoctrineException($ex);
}
} }
} }
if ($isCreate) { if ($isCreate) {
if (isset($args['dump-sql'])) { if (isset($arguments['dump-sql'])) {
foreach ($tool->getCreateSchemaSql($classes) as $sql) { foreach ($tool->getCreateSchemaSql($classes) as $sql) {
$printer->writeln($sql); $printer->writeln($sql);
} }
} else { } else {
$printer->writeln('Creating database schema...', 'INFO'); $printer->writeln('Creating database schema...', 'INFO');
try {
$tool->createSchema($classes); $tool->createSchema($classes);
$printer->writeln('Database schema created successfully.', 'INFO'); $printer->writeln('Database schema created successfully.', 'INFO');
} catch (\Exception $ex) {
throw new DoctrineException($ex);
}
} }
} }
if ($isUpdate || $isCompleteUpdate) { if ($isUpdate || $isCompleteUpdate) {
$saveMode = $isUpdate?true:false; $saveMode = $isUpdate ? true : false;
if (isset($args['dump-sql'])) {
if (isset($arguments['dump-sql'])) {
foreach ($tool->getUpdateSchemaSql($classes, $saveMode) as $sql) { foreach ($tool->getUpdateSchemaSql($classes, $saveMode) as $sql) {
$printer->writeln($sql); $printer->writeln($sql);
} }
} else { } else {
$printer->writeln('Updating database schema...', 'INFO'); $printer->writeln('Updating database schema...', 'INFO');
try {
$tool->updateSchema($classes, $saveMode); $tool->updateSchema($classes, $saveMode);
$printer->writeln('Database schema updated successfully.', 'INFO'); $printer->writeln('Database schema updated successfully.', 'INFO');
} catch (\Exception $ex) {
throw new DoctrineException($ex);
}
} }
} }
} }
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
namespace Doctrine\ORM\Tools\Cli\Tasks; namespace Doctrine\ORM\Tools\Cli\Tasks;
use Doctrine\Common\Cli\Tasks\AbstractTask;
/** /**
* CLI Task to display the doctrine version * CLI Task to display the doctrine version
* *
...@@ -28,6 +30,7 @@ namespace Doctrine\ORM\Tools\Cli\Tasks; ...@@ -28,6 +30,7 @@ namespace Doctrine\ORM\Tools\Cli\Tasks;
* @link www.doctrine-project.org * @link www.doctrine-project.org
* @since 2.0 * @since 2.0
* @version $Revision$ * @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com> * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com> * @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
...@@ -47,14 +50,6 @@ class VersionTask extends AbstractTask ...@@ -47,14 +50,6 @@ class VersionTask extends AbstractTask
->setDescription('Displays the current installed Doctrine version.'); ->setDescription('Displays the current installed Doctrine version.');
} }
/**
* @inheritdoc
*/
public function validate()
{
return true;
}
/** /**
* Displays the current version of Doctrine * Displays the current version of Doctrine
* *
......
...@@ -32,9 +32,7 @@ $connectionOptions = array( ...@@ -32,9 +32,7 @@ $connectionOptions = array(
'path' => 'database.sqlite' 'path' => 'database.sqlite'
); );
// These are required named variables (names can't change!)
$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config); $em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
$globalArguments = array( $configuration = new \Doctrine\Common\Cli\Configuration();
'class-dir' => './Entities' $configuration->setAttribute('em', $em);
); \ No newline at end of file
\ No newline at end of file
<?php <?php
require __DIR__ . '/../../lib/Doctrine/Common/ClassLoader.php'; require_once __DIR__ . '/../../lib/Doctrine/Common/ClassLoader.php';
$classLoader = new \Doctrine\Common\ClassLoader('Doctrine', __DIR__ . '/../../lib'); $classLoader = new \Doctrine\Common\ClassLoader();
$classLoader->setIncludePath(__DIR__ . '/../../lib');
$classLoader->register(); $classLoader->register();
$cli = new \Doctrine\ORM\Tools\Cli\CliController(); // Variable $configuration is defined inside cli-config.php
require_once __DIR__ . '/cli-config.php';
$cli = new \Doctrine\Common\Cli\CliController($configuration);
$cli->run($_SERVER['argv']); $cli->run($_SERVER['argv']);
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment