From a5bf1088e48a43e7d8cbf7f24f5da8addfbd4068 Mon Sep 17 00:00:00 2001 From: Johannes Wachter Date: Mon, 5 Feb 2018 15:48:32 +0100 Subject: [PATCH 1/4] added option to control the uuid-behavior --- .../Command/WorkspaceImportCommand.php | 33 ++++++++++++++++--- src/PHPCR/Util/NodeHelper.php | 8 ++--- .../Command/WorkspaceImportCommandTest.php | 30 ++++++++++++++--- 3 files changed, 58 insertions(+), 13 deletions(-) diff --git a/src/PHPCR/Util/Console/Command/WorkspaceImportCommand.php b/src/PHPCR/Util/Console/Command/WorkspaceImportCommand.php index 1bf356d..85960bb 100644 --- a/src/PHPCR/Util/Console/Command/WorkspaceImportCommand.php +++ b/src/PHPCR/Util/Console/Command/WorkspaceImportCommand.php @@ -19,6 +19,13 @@ */ class WorkspaceImportCommand extends BaseCommand { + private static $uuidBehavior = array( + 'new' => ImportUUIDBehaviorInterface::IMPORT_UUID_CREATE_NEW, + 'remove' => ImportUUIDBehaviorInterface::IMPORT_UUID_COLLISION_REMOVE_EXISTING, + 'replace' => ImportUUIDBehaviorInterface::IMPORT_UUID_COLLISION_REPLACE_EXISTING, + 'throw' => ImportUUIDBehaviorInterface::IMPORT_UUID_COLLISION_THROW, + ); + /** * {@inheritDoc} */ @@ -30,6 +37,7 @@ protected function configure() ->setName('phpcr:workspace:import') ->addArgument('filename', null, 'The xml file to import') ->addOption('parentpath', 'p', InputOption::VALUE_OPTIONAL, 'Repository path to the parent where to import the file contents', '/') + ->addOption('uuid-behavior', null, InputOption::VALUE_REQUIRED, 'How to handle UUID collisions during the import', 'new') ->setDescription('Import xml data into the repository, either in JCR system view format or arbitrary xml') ->setHelp(<<import command uses the PHPCR SessionInterface::importXml method @@ -40,6 +48,17 @@ protected function configure() If the parentpath option is set, the document is imported to that path. Otherwise the document is imported at the repository root. + +The optional uuid-behavior option describes how UUIDs should be +handled. The following options are available: + +* new recreate a new uuid for each imported node; +* remove on collision, remove the old node from the repository and + put the imported data in the tree; +* replace on collision, replace the existing node with the one being + imported. All children of the imported node also go to the new path; +* throw throw an exception on uuid collision. + EOF ) ; @@ -61,11 +80,15 @@ protected function execute(InputInterface $input, OutputInterface $output) return 1; } - $session->importXml( - $parentPath, - $filename, - ImportUUIDBehaviorInterface::IMPORT_UUID_CREATE_NEW - ); + $uuidBehavior = $input->getOption('uuid-behavior'); + if (!array_key_exists($uuidBehavior, self::$uuidBehavior)) { + $output->writeln(sprintf('UUID-Behavior "%s" is not supported', $uuidBehavior)); + $output->writeln(sprintf('Supported behaviors are %s', implode(', ', array_keys(self::$uuidBehavior)))); + + return 1; + } + + $session->importXML($parentPath, $filename, self::$uuidBehavior[$uuidBehavior]); $session->save(); $output->writeln(sprintf( diff --git a/src/PHPCR/Util/NodeHelper.php b/src/PHPCR/Util/NodeHelper.php index 778e647..7e6b627 100644 --- a/src/PHPCR/Util/NodeHelper.php +++ b/src/PHPCR/Util/NodeHelper.php @@ -154,10 +154,10 @@ public static function generateAutoNodeName($usedNames, $namespaces, $defaultNam return self::generateWithPrefix($usedNames, ''); } - /* - * "somePrefix:" where somePrefix is a syntactically - * valid namespace prefix - */ + /* + * "somePrefix:" where somePrefix is a syntactically + * valid namespace prefix + */ if (':' == $nameHint[strlen($nameHint)-1] && substr_count($nameHint, ':') === 1 && preg_match('#^[a-zA-Z][a-zA-Z0-9]*:$#', $nameHint) diff --git a/tests/PHPCR/Tests/Util/Console/Command/WorkspaceImportCommandTest.php b/tests/PHPCR/Tests/Util/Console/Command/WorkspaceImportCommandTest.php index d4641a5..8c5c6af 100644 --- a/tests/PHPCR/Tests/Util/Console/Command/WorkspaceImportCommandTest.php +++ b/tests/PHPCR/Tests/Util/Console/Command/WorkspaceImportCommandTest.php @@ -2,9 +2,9 @@ namespace PHPCR\Tests\Util\Console\Command; -use Symfony\Component\Console\Application; -use PHPCR\Util\Console\Command\WorkspaceImportCommand; +use PHPCR\ImportUUIDBehaviorInterface; use PHPCR\RepositoryInterface; +use PHPCR\Util\Console\Command\WorkspaceImportCommand; class WorkspaceImportCommandTest extends BaseCommandTest { @@ -14,7 +14,7 @@ public function setUp() $this->application->add(new WorkspaceImportCommand()); } - public function testNodeTypeList() + public function testImport() { $this->session->expects($this->once()) ->method('getRepository') @@ -24,7 +24,8 @@ public function testNodeTypeList() ->with(RepositoryInterface::OPTION_XML_IMPORT_SUPPORTED) ->will($this->returnValue(true)); $this->session->expects($this->once()) - ->method('importXml'); + ->method('importXml') + ->with('/', 'test_import.xml', ImportUUIDBehaviorInterface::IMPORT_UUID_CREATE_NEW); $ct = $this->executeCommand('phpcr:workspace:import', array( 'filename' => 'test_import.xml' @@ -32,4 +33,25 @@ public function testNodeTypeList() $this->assertContains('Successfully imported', $ct->getDisplay()); } + + public function testImportUuidBehaviorThrow() + { + $this->session->expects($this->once()) + ->method('getRepository') + ->will($this->returnValue($this->repository)); + $this->repository->expects($this->once()) + ->method('getDescriptor') + ->with(RepositoryInterface::OPTION_XML_IMPORT_SUPPORTED) + ->will($this->returnValue(true)); + $this->session->expects($this->once()) + ->method('importXml') + ->with('/', 'test_import.xml', ImportUUIDBehaviorInterface::IMPORT_UUID_COLLISION_THROW); + + $ct = $this->executeCommand('phpcr:workspace:import', array( + 'filename' => 'test_import.xml', + '--uuid-behavior' => 'throw', + )); + + $this->assertContains('Successfully imported', $ct->getDisplay()); + } } From bd160975217230b881c870a7dc08d8daa4d80b22 Mon Sep 17 00:00:00 2001 From: Johannes Wachter Date: Fri, 9 Feb 2018 08:14:45 +0100 Subject: [PATCH 2/4] fixed testcases --- .travis.yml | 1 + src/PHPCR/Util/QOM/Sql2Scanner.php | 2 +- .../Console/Command/NodesUpdateCommandTest.php | 2 +- .../Tests/Util/QOM/Sql2ToQomQueryConverterTest.php | 14 ++++++++++++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 575f3aa..b61f75b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,7 @@ sudo: false matrix: include: - php: 5.3 + dist: precise env: PACKAGE_VERSION=low before_script: diff --git a/src/PHPCR/Util/QOM/Sql2Scanner.php b/src/PHPCR/Util/QOM/Sql2Scanner.php index ac9a51c..49fd370 100644 --- a/src/PHPCR/Util/QOM/Sql2Scanner.php +++ b/src/PHPCR/Util/QOM/Sql2Scanner.php @@ -159,7 +159,7 @@ protected function scan($sql2) $token = strtok(" \n\t"); } - $regexp = ''; + $regexp = array(); foreach ($tokens as $token) { $regexp[] = preg_quote($token, '/'); } diff --git a/tests/PHPCR/Tests/Util/Console/Command/NodesUpdateCommandTest.php b/tests/PHPCR/Tests/Util/Console/Command/NodesUpdateCommandTest.php index db523a2..fe90059 100644 --- a/tests/PHPCR/Tests/Util/Console/Command/NodesUpdateCommandTest.php +++ b/tests/PHPCR/Tests/Util/Console/Command/NodesUpdateCommandTest.php @@ -88,7 +88,7 @@ public function testNodeUpdate($options) $this->setupQueryManager($options); $args = array( - '--query-language' => null, + '--query-language' => 'jcr-sql2', '--query' => $options['query'], '--no-interaction' => true, '--set-prop' => array(), diff --git a/tests/PHPCR/Tests/Util/QOM/Sql2ToQomQueryConverterTest.php b/tests/PHPCR/Tests/Util/QOM/Sql2ToQomQueryConverterTest.php index 15def8d..e1e4ac1 100644 --- a/tests/PHPCR/Tests/Util/QOM/Sql2ToQomQueryConverterTest.php +++ b/tests/PHPCR/Tests/Util/QOM/Sql2ToQomQueryConverterTest.php @@ -2,13 +2,27 @@ namespace PHPCR\Tests\Util\QOM; +use PHPCR\Query\QOM\QueryObjectModelFactoryInterface; use PHPCR\Util\QOM\Sql2ToQomQueryConverter; +use PHPCR\Util\ValueConverter; class Sql2ToQomQueryConverterTest extends \PHPUnit_Framework_TestCase { + /** + * @var QueryObjectModelFactoryInterface + */ protected $qomFactory; + + /** + * @var ValueConverter + */ protected $valueConverter; + /** + * @var Sql2ToQomQueryConverter + */ + protected $converter; + public function setUp() { $this->qomFactory = $this->getMock('PHPCR\Query\QOM\QueryObjectModelFactoryInterface'); From 9c3a01902b41459d41a611b0f0f165b7c5b37043 Mon Sep 17 00:00:00 2001 From: Johannes Wachter Date: Mon, 12 Feb 2018 15:26:09 +0100 Subject: [PATCH 3/4] changed static variable to const --- .../Util/Console/Command/WorkspaceImportCommand.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/PHPCR/Util/Console/Command/WorkspaceImportCommand.php b/src/PHPCR/Util/Console/Command/WorkspaceImportCommand.php index c5980cb..cd12d3f 100644 --- a/src/PHPCR/Util/Console/Command/WorkspaceImportCommand.php +++ b/src/PHPCR/Util/Console/Command/WorkspaceImportCommand.php @@ -18,12 +18,12 @@ */ class WorkspaceImportCommand extends BaseCommand { - private static $uuidBehavior = array( + const UUID_BEHAVIOR = [ 'new' => ImportUUIDBehaviorInterface::IMPORT_UUID_CREATE_NEW, 'remove' => ImportUUIDBehaviorInterface::IMPORT_UUID_COLLISION_REMOVE_EXISTING, 'replace' => ImportUUIDBehaviorInterface::IMPORT_UUID_COLLISION_REPLACE_EXISTING, 'throw' => ImportUUIDBehaviorInterface::IMPORT_UUID_COLLISION_THROW, - ); + ]; /** * {@inheritDoc} @@ -80,14 +80,14 @@ protected function execute(InputInterface $input, OutputInterface $output) } $uuidBehavior = $input->getOption('uuid-behavior'); - if (!array_key_exists($uuidBehavior, self::$uuidBehavior)) { + if (!array_key_exists($uuidBehavior, self::UUID_BEHAVIOR)) { $output->writeln(sprintf('UUID-Behavior "%s" is not supported', $uuidBehavior)); - $output->writeln(sprintf('Supported behaviors are %s', implode(', ', array_keys(self::$uuidBehavior)))); + $output->writeln(sprintf('Supported behaviors are %s', implode(', ', array_keys(self::UUID_BEHAVIOR)))); return 1; } - $session->importXML($parentPath, $filename, self::$uuidBehavior[$uuidBehavior]); + $session->importXML($parentPath, $filename, self::UUID_BEHAVIOR[$uuidBehavior]); $session->save(); $output->writeln(sprintf( From d30f84f6f38bb23d3b449dcb61bc79c6802492a0 Mon Sep 17 00:00:00 2001 From: Johannes Wachter Date: Tue, 13 Feb 2018 08:03:21 +0100 Subject: [PATCH 4/4] removed unused option in testcase --- .../PHPCR/Tests/Util/Console/Command/NodesUpdateCommandTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/PHPCR/Tests/Util/Console/Command/NodesUpdateCommandTest.php b/tests/PHPCR/Tests/Util/Console/Command/NodesUpdateCommandTest.php index 3d6b194..b07b67e 100644 --- a/tests/PHPCR/Tests/Util/Console/Command/NodesUpdateCommandTest.php +++ b/tests/PHPCR/Tests/Util/Console/Command/NodesUpdateCommandTest.php @@ -94,7 +94,6 @@ public function testNodeUpdate($options) $this->setupQueryManager($options); $args = [ - '--query-language' => 'jcr-sql2', '--query' => $options['query'], '--no-interaction' => true, '--set-prop' => [],