diff --git a/CHANGELOG.md b/CHANGELOG.md index c9ff211d..98c90125 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ dev-master ### Bug Fixes +- [query] Disabled updating multivalue properties where properties have more + than one value with the UPDATE, as currently other items are overwritten and + data is lost. See: https://github.com/phpcr/phpcr-shell/issues/85 - [shell] Multivalue (and so multiline) property values are truncated as a single string (#70) alpha-4 diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 7ff2c64e..0c78618c 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -722,6 +722,23 @@ public function theNodeAtShouldHaveThePropertyWithValue($arg1, $arg2, $arg3) PHPUnit_Framework_Assert::assertEquals($arg3, $propertyType); } + /** + * @Given /^the node at "([^"]*)" should have the property "([^"]*)" with value "([^"]*)" at index "([^"]*)"$/ + */ + public function theNodeAtShouldHaveThePropertyWithValueAtIndex($arg1, $arg2, $arg3, $index) + { + $session = $this->getSession(); + $node = $session->getNode($arg1); + $property = $node->getProperty($arg2); + if (!$property->isMultiple()) { + throw new \Exception('Property is not multiple and you wanted to check an index'); + } + + $propertyType = $property->getValue(); + PHPUnit_Framework_Assert::assertEquals($arg3, $propertyType[$index]); + } + + /** * @Given /^the property "([^"]*)" should have type "([^"]*)" and value "([^"]*)"$/ */ diff --git a/features/fixtures/cms.xml b/features/fixtures/cms.xml index 420ae94c..15542215 100644 --- a/features/fixtures/cms.xml +++ b/features/fixtures/cms.xml @@ -78,6 +78,14 @@ Article 1 + + Planes + Trains + Automobiles + + + Planes + diff --git a/features/phpcr_query_update.feature b/features/phpcr_query_update.feature index 0259375b..8cbec7b2 100644 --- a/features/phpcr_query_update.feature +++ b/features/phpcr_query_update.feature @@ -7,7 +7,7 @@ Feature: Execute a a raw UPDATE query in JCR_SQL2 Given that I am logged in as "testuser" And the "cms.xml" fixtures are loaded - Scenario Outline: Execute query + Scenario Outline: Execute update query Given I execute the "" command Then the command should not fail And I save the session @@ -23,3 +23,22 @@ Feature: Execute a a raw UPDATE query in JCR_SQL2 | UPDATE nt:unstructured AS a SET a.title = 'DTL' WHERE localname() = 'article1' | /cms/articles/article1 | title | DTL | | UPDATE nt:unstructured AS a SET title = 'DTL' WHERE localname() = 'article1' | /cms/articles/article1 | title | DTL | | UPDATE nt:unstructured AS a SET title = 'DTL', foobar='barfoo' WHERE localname() = 'article1' | /cms/articles/article1 | foobar | barfoo | + + Scenario: Update multivalue index by value + Given I execute the "UPDATE [nt:unstructured] AS a SET a.tags = 'Rockets' WHERE a.tags = 'Trains'" command + And I save the session + Then the command should not fail + And I should see the following: + """ + Cannot update property "tags". Updating multi-value nodes with more than one element not currently supported + """ + + Scenario: Update single multivalue + Given I execute the "UPDATE [nt:unstructured] AS a SET a.tag = 'Rockets' WHERE a.tags = 'Planes'" command + And I save the session + Then the command should not fail + And I should see the following: + """ + 1 row(s) affected + """ + And the node at "/cms/articles/article1" should have the property "tag" with value "Rockets" at index "0" diff --git a/src/PHPCR/Shell/Console/Command/Phpcr/QueryUpdateCommand.php b/src/PHPCR/Shell/Console/Command/Phpcr/QueryUpdateCommand.php index 9b48456d..cbd442c4 100644 --- a/src/PHPCR/Shell/Console/Command/Phpcr/QueryUpdateCommand.php +++ b/src/PHPCR/Shell/Console/Command/Phpcr/QueryUpdateCommand.php @@ -52,6 +52,28 @@ public function execute(InputInterface $input, OutputInterface $output) $rows++; foreach ($updates as $field => $property) { $node = $row->getNode($property['selector']); + + if ($node->hasProperty($property['name'])) { + $phpcrProperty = $node->getProperty($property['name']); + + if ($phpcrProperty->isMultiple()) { + $currentValue = $phpcrProperty->getValue(); + + if (sizeof($currentValue) > 1) { + $output->writeln(sprintf( + 'Cannot update property "%s". Updating multi-value nodes with more than one element not currently supported', + $phpcrProperty->getName() + )); + $output->writeln(sprintf( + 'See: https://github.com/phpcr/phpcr-shell/issues/81', + $phpcrProperty->getName() + )); + } + + $property['value'] = (array) $property['value']; + } + } + $node->setProperty($property['name'], $property['value']); } } diff --git a/src/PHPCR/Shell/Query/UpdateParser.php b/src/PHPCR/Shell/Query/UpdateParser.php index b2d7686e..2511ebc4 100644 --- a/src/PHPCR/Shell/Query/UpdateParser.php +++ b/src/PHPCR/Shell/Query/UpdateParser.php @@ -60,7 +60,7 @@ public function parse($sql2) $query = $this->factory->createQuery($source, $constraint); - $res = new \ArrayObject(array($query, $updates)); + $res = new \ArrayObject(array($query, $updates, $constraint)); return $res; }