Skip to content

Commit 3fe0993

Browse files
committed
Merge pull request #86 from phpcr/query_update_multivalue_fix
Prevent invalid behavior on UPDATE
2 parents 9515c6f + 73dd4bb commit 3fe0993

File tree

6 files changed

+71
-2
lines changed

6 files changed

+71
-2
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ dev-master
1212

1313
### Bug Fixes
1414

15+
- [query] Disabled updating multivalue properties where properties have more
16+
than one value with the UPDATE, as currently other items are overwritten and
17+
data is lost. See: https://github.com/phpcr/phpcr-shell/issues/85
1518
- [shell] Multivalue (and so multiline) property values are truncated as a single string (#70)
1619

1720
alpha-4

features/bootstrap/FeatureContext.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,23 @@ public function theNodeAtShouldHaveThePropertyWithValue($arg1, $arg2, $arg3)
722722
PHPUnit_Framework_Assert::assertEquals($arg3, $propertyType);
723723
}
724724

725+
/**
726+
* @Given /^the node at "([^"]*)" should have the property "([^"]*)" with value "([^"]*)" at index "([^"]*)"$/
727+
*/
728+
public function theNodeAtShouldHaveThePropertyWithValueAtIndex($arg1, $arg2, $arg3, $index)
729+
{
730+
$session = $this->getSession();
731+
$node = $session->getNode($arg1);
732+
$property = $node->getProperty($arg2);
733+
if (!$property->isMultiple()) {
734+
throw new \Exception('Property is not multiple and you wanted to check an index');
735+
}
736+
737+
$propertyType = $property->getValue();
738+
PHPUnit_Framework_Assert::assertEquals($arg3, $propertyType[$index]);
739+
}
740+
741+
725742
/**
726743
* @Given /^the property "([^"]*)" should have type "([^"]*)" and value "([^"]*)"$/
727744
*/

features/fixtures/cms.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,14 @@
7878
<sv:property sv:name="title" sv:type="String">
7979
<sv:value>Article 1</sv:value>
8080
</sv:property>
81+
<sv:property sv:name="tags" sv:type="String" sv:multiple="true">
82+
<sv:value>Planes</sv:value>
83+
<sv:value>Trains</sv:value>
84+
<sv:value>Automobiles</sv:value>
85+
</sv:property>
86+
<sv:property sv:name="tag" sv:type="String" sv:multiple="true">
87+
<sv:value>Planes</sv:value>
88+
</sv:property>
8189
</sv:node>
8290
</sv:node>
8391
</sv:node>

features/phpcr_query_update.feature

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Feature: Execute a a raw UPDATE query in JCR_SQL2
77
Given that I am logged in as "testuser"
88
And the "cms.xml" fixtures are loaded
99

10-
Scenario Outline: Execute query
10+
Scenario Outline: Execute update query
1111
Given I execute the "<query>" command
1212
Then the command should not fail
1313
And I save the session
@@ -23,3 +23,22 @@ Feature: Execute a a raw UPDATE query in JCR_SQL2
2323
| UPDATE nt:unstructured AS a SET a.title = 'DTL' WHERE localname() = 'article1' | /cms/articles/article1 | title | DTL |
2424
| UPDATE nt:unstructured AS a SET title = 'DTL' WHERE localname() = 'article1' | /cms/articles/article1 | title | DTL |
2525
| UPDATE nt:unstructured AS a SET title = 'DTL', foobar='barfoo' WHERE localname() = 'article1' | /cms/articles/article1 | foobar | barfoo |
26+
27+
Scenario: Update multivalue index by value
28+
Given I execute the "UPDATE [nt:unstructured] AS a SET a.tags = 'Rockets' WHERE a.tags = 'Trains'" command
29+
And I save the session
30+
Then the command should not fail
31+
And I should see the following:
32+
"""
33+
Cannot update property "tags". Updating multi-value nodes with more than one element not currently supported
34+
"""
35+
36+
Scenario: Update single multivalue
37+
Given I execute the "UPDATE [nt:unstructured] AS a SET a.tag = 'Rockets' WHERE a.tags = 'Planes'" command
38+
And I save the session
39+
Then the command should not fail
40+
And I should see the following:
41+
"""
42+
1 row(s) affected
43+
"""
44+
And the node at "/cms/articles/article1" should have the property "tag" with value "Rockets" at index "0"

src/PHPCR/Shell/Console/Command/Phpcr/QueryUpdateCommand.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,28 @@ public function execute(InputInterface $input, OutputInterface $output)
5252
$rows++;
5353
foreach ($updates as $field => $property) {
5454
$node = $row->getNode($property['selector']);
55+
56+
if ($node->hasProperty($property['name'])) {
57+
$phpcrProperty = $node->getProperty($property['name']);
58+
59+
if ($phpcrProperty->isMultiple()) {
60+
$currentValue = $phpcrProperty->getValue();
61+
62+
if (sizeof($currentValue) > 1) {
63+
$output->writeln(sprintf(
64+
'<error>Cannot update property "%s". Updating multi-value nodes with more than one element not currently supported</error>',
65+
$phpcrProperty->getName()
66+
));
67+
$output->writeln(sprintf(
68+
'<error>See: https://github.com/phpcr/phpcr-shell/issues/81</error>',
69+
$phpcrProperty->getName()
70+
));
71+
}
72+
73+
$property['value'] = (array) $property['value'];
74+
}
75+
}
76+
5577
$node->setProperty($property['name'], $property['value']);
5678
}
5779
}

src/PHPCR/Shell/Query/UpdateParser.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public function parse($sql2)
6060

6161
$query = $this->factory->createQuery($source, $constraint);
6262

63-
$res = new \ArrayObject(array($query, $updates));
63+
$res = new \ArrayObject(array($query, $updates, $constraint));
6464

6565
return $res;
6666
}

0 commit comments

Comments
 (0)