diff --git a/bin/doctrine-dbal.php b/bin/doctrine-dbal.php index f3e064ffd62..61a4098c9b0 100644 --- a/bin/doctrine-dbal.php +++ b/bin/doctrine-dbal.php @@ -1,5 +1,6 @@ SQLAnywhere16Keywords::class, ]; + /** @var ConnectionProvider|null */ + private $connectionProvider; + + public function __construct(?ConnectionProvider $connectionProvider = null) + { + parent::__construct(); + $this->connectionProvider = $connectionProvider; + if ($connectionProvider !== null) { + return; + } + + @trigger_error('Not passing a connection provider as the first constructor argument is deprecated', E_USER_DEPRECATED); + } + /** * If you want to add or replace a keywords list use this command. * @@ -73,12 +92,14 @@ protected function configure() $this ->setName('dbal:reserved-words') ->setDescription('Checks if the current database contains identifiers that are reserved.') - ->setDefinition([new InputOption( - 'list', - 'l', - InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, - 'Keyword-List name.' - ), + ->setDefinition([ + new InputOption('connection', null, InputOption::VALUE_REQUIRED, 'The named database connection'), + new InputOption( + 'list', + 'l', + InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, + 'Keyword-List name.' + ), ]) ->setHelp(<<getHelper('db')->getConnection(); - assert($conn instanceof Connection); + $conn = $this->getConnection($input); $keywordLists = (array) $input->getOption('list'); if (! $keywordLists) { @@ -178,4 +198,24 @@ protected function execute(InputInterface $input, OutputInterface $output) return 0; } + + private function getConnection(InputInterface $input) : Connection + { + $connectionName = $input->getOption('connection'); + assert(is_string($connectionName) || $connectionName === null); + + if ($this->connectionProvider === null) { + if ($connectionName !== null) { + throw new Exception('Specifying a connection is only supported when a ConnectionProvider is used.'); + } + + return $this->getHelper('db')->getConnection(); + } + + if ($connectionName !== null) { + return $this->connectionProvider->getConnection($connectionName); + } + + return $this->connectionProvider->getDefaultConnection(); + } } diff --git a/lib/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php b/lib/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php index 5111a6505db..37c3c8973ca 100644 --- a/lib/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php +++ b/lib/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php @@ -2,7 +2,10 @@ namespace Doctrine\DBAL\Tools\Console\Command; +use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Tools\Console\ConnectionProvider; use Doctrine\DBAL\Tools\Dumper; +use Exception; use LogicException; use RuntimeException; use Symfony\Component\Console\Command\Command; @@ -14,6 +17,8 @@ use function is_numeric; use function is_string; use function stripos; +use function trigger_error; +use const E_USER_DEPRECATED; /** * Task for executing arbitrary SQL that can come from a file or directly from @@ -21,6 +26,20 @@ */ class RunSqlCommand extends Command { + /** @var ConnectionProvider|null */ + private $connectionProvider; + + public function __construct(?ConnectionProvider $connectionProvider = null) + { + parent::__construct(); + $this->connectionProvider = $connectionProvider; + if ($connectionProvider !== null) { + return; + } + + @trigger_error('Not passing a connection provider as the first constructor argument is deprecated', E_USER_DEPRECATED); + } + /** @return void */ protected function configure() { @@ -28,6 +47,7 @@ protected function configure() ->setName('dbal:run-sql') ->setDescription('Executes arbitrary SQL directly from the command line.') ->setDefinition([ + new InputOption('connection', null, InputOption::VALUE_REQUIRED, 'The named database connection'), new InputArgument('sql', InputArgument::REQUIRED, 'The SQL statement to execute.'), new InputOption('depth', null, InputOption::VALUE_REQUIRED, 'Dumping depth of result set.', 7), new InputOption('force-fetch', null, InputOption::VALUE_NONE, 'Forces fetching the result.'), @@ -43,7 +63,7 @@ protected function configure() */ protected function execute(InputInterface $input, OutputInterface $output) { - $conn = $this->getHelper('db')->getConnection(); + $conn = $this->getConnection($input); $sql = $input->getArgument('sql'); @@ -69,4 +89,24 @@ protected function execute(InputInterface $input, OutputInterface $output) return 0; } + + private function getConnection(InputInterface $input) : Connection + { + $connectionName = $input->getOption('connection'); + assert(is_string($connectionName) || $connectionName === null); + + if ($this->connectionProvider === null) { + if ($connectionName !== null) { + throw new Exception('Specifying a connection is only supported when a ConnectionProvider is used.'); + } + + return $this->getHelper('db')->getConnection(); + } + + if ($connectionName !== null) { + return $this->connectionProvider->getConnection($connectionName); + } + + return $this->connectionProvider->getDefaultConnection(); + } } diff --git a/lib/Doctrine/DBAL/Tools/Console/ConnectionNotFound.php b/lib/Doctrine/DBAL/Tools/Console/ConnectionNotFound.php new file mode 100644 index 00000000000..81ca4182a03 --- /dev/null +++ b/lib/Doctrine/DBAL/Tools/Console/ConnectionNotFound.php @@ -0,0 +1,9 @@ +connection = $connection; + $this->defaultConnectionName = $defaultConnectionName; + } + + public function getDefaultConnection() : Connection + { + return $this->connection; + } + + public function getConnection(string $name) : Connection + { + if ($name !== $this->defaultConnectionName) { + throw new ConnectionNotFound(sprintf('Connection with name "%s" does not exist.', $name)); + } + + return $this->connection; + } +} diff --git a/lib/Doctrine/DBAL/Tools/Console/ConsoleRunner.php b/lib/Doctrine/DBAL/Tools/Console/ConsoleRunner.php index e028c807c01..f0e65c33928 100644 --- a/lib/Doctrine/DBAL/Tools/Console/ConsoleRunner.php +++ b/lib/Doctrine/DBAL/Tools/Console/ConsoleRunner.php @@ -11,6 +11,10 @@ use Symfony\Component\Console\Application; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Helper\HelperSet; +use TypeError; +use function sprintf; +use function trigger_error; +use const E_USER_DEPRECATED; /** * Handles running the Console Tools inside Symfony Console context. @@ -20,6 +24,8 @@ class ConsoleRunner /** * Create a Symfony Console HelperSet * + * @deprecated use a ConnectionProvider instead. + * * @return HelperSet */ public static function createHelperSet(Connection $connection) @@ -30,20 +36,31 @@ public static function createHelperSet(Connection $connection) } /** - * Runs console with the given helperset. + * Runs console with the given connection provider or helperset (deprecated). * - * @param Command[] $commands + * @param ConnectionProvider|HelperSet $helperSetOrConnectionProvider + * @param Command[] $commands * * @return void */ - public static function run(HelperSet $helperSet, $commands = []) + public static function run($helperSetOrConnectionProvider, $commands = []) { $cli = new Application('Doctrine Command Line Interface', Version::VERSION); $cli->setCatchExceptions(true); - $cli->setHelperSet($helperSet); - self::addCommands($cli); + $connectionProvider = null; + if ($helperSetOrConnectionProvider instanceof HelperSet) { + @trigger_error(sprintf('Passing an instance of "%s" as the first argument is deprecated. Pass an instance of "%s" instead.', HelperSet::class, ConnectionProvider::class), E_USER_DEPRECATED); + $connectionProvider = null; + $cli->setHelperSet($helperSetOrConnectionProvider); + } elseif ($helperSetOrConnectionProvider instanceof ConnectionProvider) { + $connectionProvider = $helperSetOrConnectionProvider; + } else { + throw new TypeError(sprintf('First argument must be an instance of "%s" or "%s"', HelperSet::class, ConnectionProvider::class)); + } + + self::addCommands($cli, $connectionProvider); $cli->addCommands($commands); $cli->run(); @@ -52,12 +69,12 @@ public static function run(HelperSet $helperSet, $commands = []) /** * @return void */ - public static function addCommands(Application $cli) + public static function addCommands(Application $cli, ?ConnectionProvider $connectionProvider = null) { $cli->addCommands([ - new RunSqlCommand(), + new RunSqlCommand($connectionProvider), new ImportCommand(), - new ReservedWordsCommand(), + new ReservedWordsCommand($connectionProvider), ]); } @@ -74,14 +91,17 @@ public static function printCliConfigTemplate() following sample as a template: