From 5dbd7f2fec74f431164642cf1becec71814d7878 Mon Sep 17 00:00:00 2001 From: dantleech Date: Tue, 2 Dec 2014 09:23:06 +0100 Subject: [PATCH 1/2] Allow sorting on numerical columns - New column "numerical_props" which is populated by numerical properies and which is used exlusively for ordering. --- .../DoctrineDBAL/Query/QOMWalkerTest.php | 2 +- tests/benchmark.back/queries.txt | 8 +++++ tests/benchmark.back/query_order_by.sh | 19 +++++++++++ tests/benchmark.back/resmaster.txt | 32 +++++++++++++++++++ tests/benchmark.back/resnumerical.txt | 32 +++++++++++++++++++ 5 files changed, 92 insertions(+), 1 deletion(-) create mode 100755 tests/benchmark.back/queries.txt create mode 100755 tests/benchmark.back/query_order_by.sh create mode 100755 tests/benchmark.back/resmaster.txt create mode 100755 tests/benchmark.back/resnumerical.txt diff --git a/tests/Jackalope/Transport/DoctrineDBAL/Query/QOMWalkerTest.php b/tests/Jackalope/Transport/DoctrineDBAL/Query/QOMWalkerTest.php index 8f52b27a..bb851884 100644 --- a/tests/Jackalope/Transport/DoctrineDBAL/Query/QOMWalkerTest.php +++ b/tests/Jackalope/Transport/DoctrineDBAL/Query/QOMWalkerTest.php @@ -48,7 +48,7 @@ public function testDefaultQuery() $this->nodeTypeManager->expects($this->once())->method('getSubtypes')->will($this->returnValue( array() )); $query = $this->factory->createQuery($this->factory->selector('nt:unstructured', 'nt:unstructured'), null, array(), array()); - list($selectors, $selectorAliases, $sql) = $this->walker->walkQOMQuery($query); + list($telectors, $selectorAliases, $sql) = $this->walker->walkQOMQuery($query); $this->assertEquals(sprintf("SELECT %s FROM phpcr_nodes n0 WHERE n0.workspace_name = ? AND n0.type IN ('nt:unstructured')", $this->defaultColumns), $sql); } diff --git a/tests/benchmark.back/queries.txt b/tests/benchmark.back/queries.txt new file mode 100755 index 00000000..13b98db3 --- /dev/null +++ b/tests/benchmark.back/queries.txt @@ -0,0 +1,8 @@ +SELECT \\* FROM [nt:unstructured]; +SELECT \\* FROM [nt:unstructured] ORDER BY [i18n:de-title]; +SELECT \\* FROM [nt:unstructured] AS a WHERE i18n:de-title IS NOT NULL ORDER BY [i18n:de-title]; +SELECT \\* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') AND i18n:de-title IS NOT NULL ORDER BY [sulu:order], [i18n:de-title] DESC; +SELECT \\* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service'); +SELECT \\* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') ORDER BY [i18n:de-title]; +SELECT \\* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') AND i18n:de-title IS NOT NULL ORDER BY [i18n:de-title]; +SELECT \\* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') AND i18n:de-title IS NOT NULL ORDER BY [sulu:order], [i18n:de-title] DESC; diff --git a/tests/benchmark.back/query_order_by.sh b/tests/benchmark.back/query_order_by.sh new file mode 100755 index 00000000..14b3f9c4 --- /dev/null +++ b/tests/benchmark.back/query_order_by.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +TARGET=$1 + +if [ -e $TARGET ]; then + rm $TARGET; + touch $TARGET; +fi + +while read QUERY; do + echo $QUERY + echo $QUERY >> $TARGET; + for i in 1 2 3; do + echo "." + php ~/www/phpcr/phpcr-shell/bin/phpcrsh -psulucmf --command="$QUERY" | tail -n 1 >> $TARGET + done +done < queries.txt + +cat $TARGET diff --git a/tests/benchmark.back/resmaster.txt b/tests/benchmark.back/resmaster.txt new file mode 100755 index 00000000..b650f9de --- /dev/null +++ b/tests/benchmark.back/resmaster.txt @@ -0,0 +1,32 @@ +SELECT \* FROM [nt:unstructured]; +2143 rows in set (1.85349 sec) +2143 rows in set (1.84206 sec) +2143 rows in set (1.84249 sec) +SELECT \* FROM [nt:unstructured] ORDER BY [i18n:de-title]; +2143 rows in set (1.99286 sec) +2143 rows in set (1.99348 sec) +2143 rows in set (1.97168 sec) +SELECT \* FROM [nt:unstructured] AS a WHERE i18n:de-title IS NOT NULL ORDER BY [i18n:de-title]; +330 rows in set (1.61598 sec) +330 rows in set (1.71619 sec) +330 rows in set (1.67897 sec) +SELECT \* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') AND i18n:de-title IS NOT NULL ORDER BY [sulu:order], [i18n:de-title] DESC; +57 rows in set (0.56263 sec) +57 rows in set (0.57022 sec) +57 rows in set (0.57564 sec) +SELECT \* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service'); +57 rows in set (0.49192 sec) +57 rows in set (0.48148 sec) +57 rows in set (0.48259 sec) +SELECT \* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') ORDER BY [i18n:de-title]; +57 rows in set (0.51039 sec) +57 rows in set (0.52756 sec) +57 rows in set (0.53138 sec) +SELECT \* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') AND i18n:de-title IS NOT NULL ORDER BY [i18n:de-title]; +57 rows in set (0.53312 sec) +57 rows in set (0.56196 sec) +57 rows in set (0.54788 sec) +SELECT \* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') AND i18n:de-title IS NOT NULL ORDER BY [sulu:order], [i18n:de-title] DESC; +57 rows in set (0.56275 sec) +57 rows in set (0.56514 sec) +57 rows in set (0.57182 sec) diff --git a/tests/benchmark.back/resnumerical.txt b/tests/benchmark.back/resnumerical.txt new file mode 100755 index 00000000..f3e06dd3 --- /dev/null +++ b/tests/benchmark.back/resnumerical.txt @@ -0,0 +1,32 @@ +SELECT \* FROM [nt:unstructured]; +2143 rows in set (1.84274 sec) +2143 rows in set (1.94709 sec) +2143 rows in set (1.86058 sec) +SELECT \* FROM [nt:unstructured] ORDER BY [i18n:de-title]; +2143 rows in set (2.04875 sec) +2143 rows in set (2.04055 sec) +2143 rows in set (2.00308 sec) +SELECT \* FROM [nt:unstructured] AS a WHERE i18n:de-title IS NOT NULL ORDER BY [i18n:de-title]; +330 rows in set (1.63383 sec) +330 rows in set (1.63438 sec) +330 rows in set (1.63745 sec) +SELECT \* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') AND i18n:de-title IS NOT NULL ORDER BY [sulu:order], [i18n:de-title] DESC; +57 rows in set (0.57677 sec) +57 rows in set (0.60930 sec) +57 rows in set (0.58204 sec) +SELECT \* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service'); +57 rows in set (0.48024 sec) +57 rows in set (0.47330 sec) +57 rows in set (0.48214 sec) +SELECT \* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') ORDER BY [i18n:de-title]; +57 rows in set (0.52143 sec) +57 rows in set (0.52957 sec) +57 rows in set (0.52393 sec) +SELECT \* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') AND i18n:de-title IS NOT NULL ORDER BY [i18n:de-title]; +57 rows in set (0.54349 sec) +57 rows in set (0.55270 sec) +57 rows in set (0.54978 sec) +SELECT \* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') AND i18n:de-title IS NOT NULL ORDER BY [sulu:order], [i18n:de-title] DESC; +57 rows in set (0.56815 sec) +57 rows in set (0.58603 sec) +57 rows in set (0.55674 sec) From c73cc61d89da820f2acb626ceebf1d17c0d0c78c Mon Sep 17 00:00:00 2001 From: dantleech Date: Mon, 29 Dec 2014 10:08:59 +0000 Subject: [PATCH 2/2] When copying nodes remap any references within the copied set --- .../Transport/DoctrineDBAL/Client.php | 36 +++++++++++++++++-- .../DoctrineDBAL/Query/QOMWalkerTest.php | 2 +- tests/benchmark.back/queries.txt | 8 ----- tests/benchmark.back/query_order_by.sh | 19 ---------- tests/benchmark.back/resmaster.txt | 32 ----------------- tests/benchmark.back/resnumerical.txt | 32 ----------------- 6 files changed, 34 insertions(+), 95 deletions(-) delete mode 100755 tests/benchmark.back/queries.txt delete mode 100755 tests/benchmark.back/query_order_by.sh delete mode 100755 tests/benchmark.back/resmaster.txt delete mode 100755 tests/benchmark.back/resnumerical.txt diff --git a/src/Jackalope/Transport/DoctrineDBAL/Client.php b/src/Jackalope/Transport/DoctrineDBAL/Client.php index 9b3429cc..3c8d217e 100644 --- a/src/Jackalope/Transport/DoctrineDBAL/Client.php +++ b/src/Jackalope/Transport/DoctrineDBAL/Client.php @@ -571,15 +571,23 @@ public function copyNode($srcAbsPath, $dstAbsPath, $srcWorkspace = null) $query = 'SELECT * FROM phpcr_nodes WHERE path LIKE ? AND workspace_name = ?'; $stmt = $this->conn->executeQuery($query, array($srcAbsPath . '%', $srcWorkspace)); + $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC); + + $uuidMap = array(); + $resultSetUuids = array(); + + // first iterate and build up an array of all the UUIDs in the result set + foreach ($rows as $row) { + $resultSetUuids[$row['identifier']] = $row['path']; + } - foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) { + $referenceElsToRemap = array(); + foreach ($rows as $row) { $newPath = str_replace($srcAbsPath, $dstAbsPath, $row['path']); $stringDom = new \DOMDocument('1.0', 'UTF-8'); $stringDom->loadXML($row['props']); - $numericalDom = null; - if ($row['numerical_props']) { $numericalDom = new \DOMDocument('1.0', 'UTF-8'); $numericalDom->loadXML($row['numerical_props']); @@ -589,9 +597,24 @@ public function copyNode($srcAbsPath, $dstAbsPath, $srcWorkspace = null) 'stringDom' => $stringDom, 'numericalDom' => $numericalDom ); + + $xpath = new \DOMXpath($stringDom); + $referenceEls = $xpath->query('.//sv:property[@sv:type="reference"]'); + + foreach ($referenceEls as $referenceEl) { + if (isset($resultSetUuids[$referenceEl->nodeValue])) { + $referenceElsToRemap[] = array($referenceEl, $newPath, $row['type'], $propsData); + } + } + + $originalUuid = $row['identifier']; + // when copying a node, the copy is always a new node. set $isNewNode to true $newNodeId = $this->syncNode(null, $newPath, $row['type'], true, array(), $propsData); + $newUuid = $this->nodeIdentifiers[$newPath]; + $uuidMap[$originalUuid] = $newUuid; + $query = 'INSERT INTO phpcr_binarydata (node_id, property_name, workspace_name, idx, data)'. ' SELECT ?, b.property_name, ?, b.idx, b.data FROM phpcr_binarydata b WHERE b.node_id = ?'; @@ -601,6 +624,13 @@ public function copyNode($srcAbsPath, $dstAbsPath, $srcWorkspace = null) throw new RepositoryException("Unexpected exception while copying node from $srcAbsPath to $dstAbsPath", $e->getCode(), $e); } } + + foreach ($referenceElsToRemap as $data) { + list($referenceEl, $newPath, $type, $propsData) = $data; + $referenceEl->nodeValue = $uuidMap[$referenceEl->nodeValue]; + + $this->syncNode($this->nodeIdentifiers[$newPath], $newPath, $type, false, array(), $propsData); + } } /** diff --git a/tests/Jackalope/Transport/DoctrineDBAL/Query/QOMWalkerTest.php b/tests/Jackalope/Transport/DoctrineDBAL/Query/QOMWalkerTest.php index bb851884..8f52b27a 100644 --- a/tests/Jackalope/Transport/DoctrineDBAL/Query/QOMWalkerTest.php +++ b/tests/Jackalope/Transport/DoctrineDBAL/Query/QOMWalkerTest.php @@ -48,7 +48,7 @@ public function testDefaultQuery() $this->nodeTypeManager->expects($this->once())->method('getSubtypes')->will($this->returnValue( array() )); $query = $this->factory->createQuery($this->factory->selector('nt:unstructured', 'nt:unstructured'), null, array(), array()); - list($telectors, $selectorAliases, $sql) = $this->walker->walkQOMQuery($query); + list($selectors, $selectorAliases, $sql) = $this->walker->walkQOMQuery($query); $this->assertEquals(sprintf("SELECT %s FROM phpcr_nodes n0 WHERE n0.workspace_name = ? AND n0.type IN ('nt:unstructured')", $this->defaultColumns), $sql); } diff --git a/tests/benchmark.back/queries.txt b/tests/benchmark.back/queries.txt deleted file mode 100755 index 13b98db3..00000000 --- a/tests/benchmark.back/queries.txt +++ /dev/null @@ -1,8 +0,0 @@ -SELECT \\* FROM [nt:unstructured]; -SELECT \\* FROM [nt:unstructured] ORDER BY [i18n:de-title]; -SELECT \\* FROM [nt:unstructured] AS a WHERE i18n:de-title IS NOT NULL ORDER BY [i18n:de-title]; -SELECT \\* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') AND i18n:de-title IS NOT NULL ORDER BY [sulu:order], [i18n:de-title] DESC; -SELECT \\* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service'); -SELECT \\* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') ORDER BY [i18n:de-title]; -SELECT \\* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') AND i18n:de-title IS NOT NULL ORDER BY [i18n:de-title]; -SELECT \\* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') AND i18n:de-title IS NOT NULL ORDER BY [sulu:order], [i18n:de-title] DESC; diff --git a/tests/benchmark.back/query_order_by.sh b/tests/benchmark.back/query_order_by.sh deleted file mode 100755 index 14b3f9c4..00000000 --- a/tests/benchmark.back/query_order_by.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -TARGET=$1 - -if [ -e $TARGET ]; then - rm $TARGET; - touch $TARGET; -fi - -while read QUERY; do - echo $QUERY - echo $QUERY >> $TARGET; - for i in 1 2 3; do - echo "." - php ~/www/phpcr/phpcr-shell/bin/phpcrsh -psulucmf --command="$QUERY" | tail -n 1 >> $TARGET - done -done < queries.txt - -cat $TARGET diff --git a/tests/benchmark.back/resmaster.txt b/tests/benchmark.back/resmaster.txt deleted file mode 100755 index b650f9de..00000000 --- a/tests/benchmark.back/resmaster.txt +++ /dev/null @@ -1,32 +0,0 @@ -SELECT \* FROM [nt:unstructured]; -2143 rows in set (1.85349 sec) -2143 rows in set (1.84206 sec) -2143 rows in set (1.84249 sec) -SELECT \* FROM [nt:unstructured] ORDER BY [i18n:de-title]; -2143 rows in set (1.99286 sec) -2143 rows in set (1.99348 sec) -2143 rows in set (1.97168 sec) -SELECT \* FROM [nt:unstructured] AS a WHERE i18n:de-title IS NOT NULL ORDER BY [i18n:de-title]; -330 rows in set (1.61598 sec) -330 rows in set (1.71619 sec) -330 rows in set (1.67897 sec) -SELECT \* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') AND i18n:de-title IS NOT NULL ORDER BY [sulu:order], [i18n:de-title] DESC; -57 rows in set (0.56263 sec) -57 rows in set (0.57022 sec) -57 rows in set (0.57564 sec) -SELECT \* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service'); -57 rows in set (0.49192 sec) -57 rows in set (0.48148 sec) -57 rows in set (0.48259 sec) -SELECT \* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') ORDER BY [i18n:de-title]; -57 rows in set (0.51039 sec) -57 rows in set (0.52756 sec) -57 rows in set (0.53138 sec) -SELECT \* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') AND i18n:de-title IS NOT NULL ORDER BY [i18n:de-title]; -57 rows in set (0.53312 sec) -57 rows in set (0.56196 sec) -57 rows in set (0.54788 sec) -SELECT \* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') AND i18n:de-title IS NOT NULL ORDER BY [sulu:order], [i18n:de-title] DESC; -57 rows in set (0.56275 sec) -57 rows in set (0.56514 sec) -57 rows in set (0.57182 sec) diff --git a/tests/benchmark.back/resnumerical.txt b/tests/benchmark.back/resnumerical.txt deleted file mode 100755 index f3e06dd3..00000000 --- a/tests/benchmark.back/resnumerical.txt +++ /dev/null @@ -1,32 +0,0 @@ -SELECT \* FROM [nt:unstructured]; -2143 rows in set (1.84274 sec) -2143 rows in set (1.94709 sec) -2143 rows in set (1.86058 sec) -SELECT \* FROM [nt:unstructured] ORDER BY [i18n:de-title]; -2143 rows in set (2.04875 sec) -2143 rows in set (2.04055 sec) -2143 rows in set (2.00308 sec) -SELECT \* FROM [nt:unstructured] AS a WHERE i18n:de-title IS NOT NULL ORDER BY [i18n:de-title]; -330 rows in set (1.63383 sec) -330 rows in set (1.63438 sec) -330 rows in set (1.63745 sec) -SELECT \* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') AND i18n:de-title IS NOT NULL ORDER BY [sulu:order], [i18n:de-title] DESC; -57 rows in set (0.57677 sec) -57 rows in set (0.60930 sec) -57 rows in set (0.58204 sec) -SELECT \* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service'); -57 rows in set (0.48024 sec) -57 rows in set (0.47330 sec) -57 rows in set (0.48214 sec) -SELECT \* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') ORDER BY [i18n:de-title]; -57 rows in set (0.52143 sec) -57 rows in set (0.52957 sec) -57 rows in set (0.52393 sec) -SELECT \* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') AND i18n:de-title IS NOT NULL ORDER BY [i18n:de-title]; -57 rows in set (0.54349 sec) -57 rows in set (0.55270 sec) -57 rows in set (0.54978 sec) -SELECT \* FROM [nt:unstructured] AS a WHERE ISDESCENDANTNODE(a, '/cmf/stanton/contents/service') AND i18n:de-title IS NOT NULL ORDER BY [sulu:order], [i18n:de-title] DESC; -57 rows in set (0.56815 sec) -57 rows in set (0.58603 sec) -57 rows in set (0.55674 sec)