From c0aba54f21ab1b2240fbdab8346ceec5910d4587 Mon Sep 17 00:00:00 2001 From: dantleech Date: Sat, 19 Jul 2014 09:13:21 +0200 Subject: [PATCH] Added support for DELETE queries --- CHANGELOG.md | 1 + features/bootstrap/FeatureContext.php | 1 - features/phpcr_query_delete.feature | 24 +++++++ .../Console/Application/ShellApplication.php | 1 + .../Command/Phpcr/QueryDeleteCommand.php | 64 +++++++++++++++++++ src/PHPCR/Shell/Console/Input/StringInput.php | 5 ++ 6 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 features/phpcr_query_delete.feature create mode 100644 src/PHPCR/Shell/Console/Command/Phpcr/QueryDeleteCommand.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 39061d7f..141a4894 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ alpha-4 - [node|shell] Most commands which accept a node path can also accept a UUID - [node] `node:list`: Show node primary item value - [query] Support for UPDATE queries +- [query] Support for DELETE queries ### Bugs Fixes diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index b84942a1..0fe8d559 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -628,7 +628,6 @@ public function thereShouldNotExistANodeTypeNamed($arg1) try { $nodeTypeManager->getNodeType($arg1); } catch (\Exception $e) { - var_dump(get_class($e));die(); } throw new \Exception('Node type ' . $arg1 . ' exists'); diff --git a/features/phpcr_query_delete.feature b/features/phpcr_query_delete.feature new file mode 100644 index 00000000..441b8c89 --- /dev/null +++ b/features/phpcr_query_delete.feature @@ -0,0 +1,24 @@ +Feature: Execute a a raw DELETE query in JCR_SQL2 + In order to run an DELETE JCR_SQL2 query easily + As a user logged into the shell + I want to simply type the query like in a normal sql shell + + Background: + Given that I am logged in as "testuser" + And the "cms.xml" fixtures are loaded + + Scenario Outline: Execute query + Given I execute the "" command + Then the command should not fail + And there should exist a node at "" + And I save the session + And there should not exist a node at "" + And I should see the following: + """ + 1 row(s) affected + """ + Examples: + | query | path | + | DELETE FROM [nt:unstructured] AS a WHERE localname() = 'article1' | /cms/articles/article1 | + | delete FROM [nt:unstructured] as a where localname() = 'article1' | /cms/articles/article1 | + | DELETE FROM nt:unstructured AS a WHERE localname() = 'article1' | /cms/articles/article1 | diff --git a/src/PHPCR/Shell/Console/Application/ShellApplication.php b/src/PHPCR/Shell/Console/Application/ShellApplication.php index 8b59d265..8d847a7c 100644 --- a/src/PHPCR/Shell/Console/Application/ShellApplication.php +++ b/src/PHPCR/Shell/Console/Application/ShellApplication.php @@ -164,6 +164,7 @@ private function registerCommands() $this->add(new CommandPhpcr\QueryCommand()); $this->add(new CommandPhpcr\QuerySelectCommand()); $this->add(new CommandPhpcr\QueryUpdateCommand()); + $this->add(new CommandPhpcr\QueryDeleteCommand()); $this->add(new CommandPhpcr\RetentionHoldAddCommand()); $this->add(new CommandPhpcr\RetentionHoldListCommand()); $this->add(new CommandPhpcr\RetentionHoldRemoveCommand()); diff --git a/src/PHPCR/Shell/Console/Command/Phpcr/QueryDeleteCommand.php b/src/PHPCR/Shell/Console/Command/Phpcr/QueryDeleteCommand.php new file mode 100644 index 00000000..eac9d12e --- /dev/null +++ b/src/PHPCR/Shell/Console/Command/Phpcr/QueryDeleteCommand.php @@ -0,0 +1,64 @@ +setName('delete'); + $this->setDescription('Execute a literal JCR-SQL2 query'); + $this->addArgument('query'); + $this->setHelp(<<session:save to persist changes. + +Note that this command is not part of the JCR-SQL2 language but is implemented specifically +for the PHPCR-Shell. +EOT + ); + } + + public function execute(InputInterface $input, OutputInterface $output) + { + $sql = $input->getRawCommand(); + + // trim ";" for people used to MysQL + if (substr($sql, -1) == ';') { + $sql = substr($sql, 0, -1); + } + + $session = $this->getHelper('phpcr')->getSession(); + $qm = $session->getWorkspace()->getQueryManager(); + + if (!preg_match('{^delete from}', strtolower($sql))) { + throw new \PHPCR\Query\InvalidQueryException(sprintf( + '"FROM" not specified in DELETE query: "%s"', $sql + )); + } + + $sql = 'SELECT * FROM' . substr($sql, 11); + + $selectParser = new Sql2ToQomQueryConverter($qm->getQOMFactory()); + $query = $selectParser->parse($sql); + + $start = microtime(true); + $result = $query->execute(); + + foreach ($result as $row) { + $node = $row->getNode(); + $node->remove(); + } + + $elapsed = microtime(true) - $start; + $output->writeln(sprintf('%s row(s) affected in %ss', count($result), number_format($elapsed, 2))); + } +} diff --git a/src/PHPCR/Shell/Console/Input/StringInput.php b/src/PHPCR/Shell/Console/Input/StringInput.php index ff6bdecc..fc97d0fc 100644 --- a/src/PHPCR/Shell/Console/Input/StringInput.php +++ b/src/PHPCR/Shell/Console/Input/StringInput.php @@ -33,6 +33,11 @@ public function __construct($command) $this->isQuery = true; } + if (strpos(strtolower($this->rawCommand), 'delete') === 0) { + $command = 'delete' . substr($command, 6); + $this->isQuery = true; + } + parent::__construct($command); }