Skip to content

Commit

Permalink
Merge pull request #272 from danrot/versioning
Browse files Browse the repository at this point in the history
Use VersionHandler and adapt tests
  • Loading branch information
dbu committed Jun 11, 2015
2 parents 901a55f + 4d0d918 commit f3f2042
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 14 deletions.
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
"php": ">=5.3.3",
"doctrine/dbal": ">=2.4.5,<3.0.x-dev",
"phpcr/phpcr": "~2.1.2",
"phpcr/phpcr-utils": "~1.2,>=1.2.4",
"jackalope/jackalope": "~1.2.0"
"phpcr/phpcr-utils": "~1.2,>=1.2.6",
"jackalope/jackalope": "dev-versioning as 1.3.0"
},
"provide": {
"jackalope/jackalope-transport": "1.1.0"
Expand Down
3 changes: 0 additions & 3 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@

<exclude>
<!-- ignore whats not implemented yet -->
<directory>vendor/phpcr/phpcr/src/PHPCR/Version</directory>
<directory>vendor/jackalope/jackalope/src/Jackalope/Version</directory>

<directory>vendor/phpcr/phpcr/src/PHPCR/Lock</directory>
<directory>vendor/jackalope/jackalope/src/Jackalope/Lock</directory>

Expand Down
67 changes: 63 additions & 4 deletions src/Jackalope/Transport/DoctrineDBAL/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Jackalope\Transport\DoctrineDBAL;

use Jackalope\Version\GenericVersioningInterface;
use Jackalope\Version\VersionHandler;
use PHPCR\LoginException;
use PHPCR\NodeType\NodeDefinitionInterface;
use PHPCR\NodeType\NodeTypeExistsException;
Expand All @@ -24,6 +26,7 @@
use PHPCR\Query\InvalidQueryException;
use PHPCR\NodeType\ConstraintViolationException;

use PHPCR\UnsupportedRepositoryOperationException;
use PHPCR\Util\QOM\Sql2ToQomQueryConverter;
use PHPCR\Util\ValueConverter;
use PHPCR\Util\UUIDHelper;
Expand Down Expand Up @@ -52,6 +55,7 @@
use Jackalope\FactoryInterface;
use Jackalope\NotImplementedException;
use Jackalope\NodeType\NodeProcessor;
use PHPCR\Version\VersionException;

/**
* Class to handle the communication between Jackalope and RDBMS via Doctrine DBAL.
Expand All @@ -62,7 +66,7 @@
* @author Benjamin Eberlei <[email protected]>
* @author Lukas Kahwe Smith <[email protected]>
*/
class Client extends BaseTransport implements QueryTransport, WritingInterface, WorkspaceManagementInterface, NodeTypeManagementInterface, TransactionInterface
class Client extends BaseTransport implements QueryTransport, WritingInterface, WorkspaceManagementInterface, NodeTypeManagementInterface, TransactionInterface, GenericVersioningInterface
{
/**
* SQlite can only handle a maximum of 999 parameters inside an IN statement
Expand Down Expand Up @@ -177,6 +181,11 @@ class Client extends BaseTransport implements QueryTransport, WritingInterface,
*/
private $nodeProcessor;

/**
* @var VersionHandler
*/
private $versionHandler;

/**
* @param FactoryInterface $factory
* @param Connection $conn
Expand Down Expand Up @@ -1902,7 +1911,8 @@ private function getNodeProcessor()
$this->nodeProcessor = new NodeProcessor(
$this->credentials->getUserID(),
$this->getNamespacesObject(),
$this->getAutoLastModified()
$this->getAutoLastModified(),
$this->versionHandler
);

return $this->nodeProcessor;
Expand Down Expand Up @@ -2539,8 +2549,12 @@ public function rollbackSave()
public function updateProperties(Node $node)
{
$this->assertLoggedIn();
// we can ignore the operations returned, there will be no additions because of property updates
$this->getNodeProcessor()->process($node);

$additionalAddOperations = $this->getNodeProcessor()->process($node);

if (!empty($additionalAddOperations)) {
$this->storeNodes($additionalAddOperations);
}

$this->syncNode($node->getIdentifier(), $node->getPath(), $node->getPrimaryNodeType(), false, $node->getProperties());

Expand Down Expand Up @@ -2568,4 +2582,49 @@ private function initConnection()

$this->connectionInitialized = true;
}

/**
* {@inheritDoc}
*/
public function checkinItem($path)
{
return $this->versionHandler->checkinItem($path);
}

/**
* {@inheritDoc}
*/
public function checkoutItem($path)
{
return $this->versionHandler->checkoutItem($path);
}

/**
* {@inheritDoc}
*/
public function restoreItem($removeExisting, $versionPath, $path)
{
throw new NotImplementedException();
}

/**
* {@inheritDoc}
*/
public function removeVersion($versionPath, $versionName)
{
throw new NotImplementedException();
}

/**
* Sets the generic version handler delivered by jackalope
* @param VersionHandler $versionHandler
*/
public function setVersionHandler(VersionHandler $versionHandler)
{
if ($this->versionHandler) {
throw new \InvalidArgumentException('Version handler is already set');
}

$this->versionHandler = $versionHandler;
}
}
8 changes: 6 additions & 2 deletions tests/ImplementationLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,18 @@ protected function __construct(Connection $connection, $fixturePath)
'SameNameSiblings', //TODO: Not implemented, no test currently written for it
'PermissionsAndCapabilities', //TODO: Transport does not support permissions
'Observation', //TODO: Transport does not support observation
'Versioning', //TODO: Transport does not support versioning
'Locking', //TODO: Transport does not support locking
);

$this->unsupportedCases = array(
'Query\\XPath', // Query language 'xpath' not implemented.
'Query\\Sql1', // Query language 'sql' is legacy and only makes sense with jackrabbit
'Writing\\CloneMethodsTest', // TODO: Support for workspace->clone, node->update, node->getCorrespondingNodePath

// TODO fully implement versioning
'Versioning\\VersionHistoryTest',
'Versioning\\VersionManagerTest',
'Versioning\\VersionTest',
);

$this->unsupportedTests = array(
Expand Down Expand Up @@ -82,7 +86,7 @@ protected function __construct(Connection $connection, $fixturePath)

// TODO: implement creating workspace with source
'WorkspaceManagement\\WorkspaceManagementTest::testCreateWorkspaceWithSource',
'WorkspaceManagement\\WorkspaceManagementTest::testCreateWorkspaceWithInvalidSource'
'WorkspaceManagement\\WorkspaceManagementTest::testCreateWorkspaceWithInvalidSource',
);

if ($connection->getDatabasePlatform() instanceof Doctrine\DBAL\Platforms\SqlitePlatform) {
Expand Down
100 changes: 97 additions & 3 deletions tests/Jackalope/Test/Fixture/DBUnitFixtureXML.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ class DBUnitFixtureXML extends XMLDocument
*/
protected $expectedNodes;

/**
* Track if root nodes exists for workspace names
* @var array
*/
private $rootNodes;

/**
* @param string $file - file path
* @param int $options - libxml option constants: http://www.php.net/manual/en/libxml.constants.php
Expand Down Expand Up @@ -101,9 +107,18 @@ public function addNamespaces(array $namespaces)
public function addNodes($workspaceName, \DOMNodeList $nodes)
{
$node = $nodes->item(0);
if ('jcr:root' !== $node->getAttributeNS($this->namespaces['sv'], 'name')) {
$this->addRootNode('tests');
if (!isset($this->rootNodes[$workspaceName])) {
if ('jcr:root' !== $node->getAttributeNS($this->namespaces['sv'], 'name')) {
$this->addRootNode('tests');
}
$this->rootNodes[$workspaceName] = true;
}

$srcDom = new \Jackalope\Test\Fixture\JCRSystemXML(__DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'fixtures' . DIRECTORY_SEPARATOR . 'system.xml');
foreach ($srcDom->load()->getNodes() as $node) {
$this->addNode($workspaceName, $node);
}

foreach ($nodes as $node) {
$this->addNode($workspaceName, $node);
}
Expand Down Expand Up @@ -188,6 +203,12 @@ public function addNode($workspaceName, \DOMElement $node)
$namespace = '';
}

if (isset($properties['jcr:mixinTypes'])
&& in_array('mix:versionable', $properties['jcr:mixinTypes']['value'])
) {
$this->addVersioningProperties($dom, $phpcrNode, $workspaceName, $id);
}

$this->addRow('phpcr_nodes', array(
'id' => $id,
'path' => $childPath,
Expand Down Expand Up @@ -261,7 +282,7 @@ public function getChildAttribute(\DOMElement $node)
$isMultiValue = true;
}

return array($name, array('type' => $type, 'value' => $values, 'multiValued' => $isMultiValue));
return array($name, array('type' => $type, 'value' => $values, 'multiValued' => $isMultiValue));
}

public function createPropertyNode($workspaceName, $propertyName, $propertyData, $id, \DOMDocument $dom)
Expand Down Expand Up @@ -414,4 +435,77 @@ protected function ensureTableExists($tableName, $columns)
return $this;
}

private function addVersioningProperties(\DOMDocument $dom, \DOMElement $node, $workspaceName, $id)
{
$node->appendChild(
$this->createPropertyNode(
$workspaceName,
'jcr:isCheckedOut',
array('type' => 'boolean', 'value' => array('true'), 'multiValued' => false),
$id,
$dom
)
);

$versionNodeUuid = UUIDHelper::generateUUID();
$versionParentPath = '/jcr:system/jcr:versionStorage';
$versionPath = $versionParentPath . '/' . $versionNodeUuid;
$this->addRow(
'phpcr_nodes',
array(
'id' => self::$idCounter++,
'path' => $versionPath,
'parent' => $versionParentPath,
'local_name' => $versionNodeUuid,
'namespace' => '',
'workspace_name' => $workspaceName,
'identifier' => $versionNodeUuid,
'type' => 'nt:unstructured',
'props' => '<?xml version="1.0" encoding="UTF-8"?>'
. '<sv:node xmlns:sv="http://www.jcp.org/jcr/sv/1.0"/>',
'depth' => PathHelper::getPathDepth($versionPath),
'sort_order' => $id - 2,
)
);

$rootVersionPath = $versionPath . '/jcr:rootVersion';
$rootVersionUuid = UUIDHelper::generateUUID();
$this->addRow(
'phpcr_nodes',
array(
'id' => self::$idCounter++,
'path' => $rootVersionPath,
'parent' => $versionPath,
'local_name' => 'jcr:rootVersion',
'namespace' => '',
'workspace_name' => $workspaceName,
'identifier' => $rootVersionUuid,
'type' => 'nt:version',
'props' => '<?xml version="1.0" encoding="UTF-8"?>'
. '<sv:node xmlns:sv="http://www.jcp.org/jcr/sv/1.0"/>',
'depth' => PathHelper::getPathDepth($rootVersionPath),
'sort_order' => $id - 2,
)
);

$node->appendChild(
$this->createPropertyNode(
$workspaceName,
'jcr:versionHistory',
array('type' => 'reference', 'value' => array($versionNodeUuid), 'multiValued' => false),
$id,
$dom
)
);

$node->appendChild(
$this->createPropertyNode(
$workspaceName,
'jcr:predecessors',
array('type' => 'reference', 'value' => array(), 'multiValued' => true),
$id,
$dom
)
);
}
}
11 changes: 11 additions & 0 deletions tests/fixtures/system.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<sv:node jcr="http://www.jcp.org/jcr/1.0" xmlns:sv="http://www.jcp.org/jcr/sv/1.0" xmlns:rep="internal" sv:name="jcr:system">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>nt:unstructured</sv:value>
</sv:property>
<sv:node sv:name="jcr:versionStorage">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>nt:unstructured</sv:value>
</sv:property>
</sv:node>
</sv:node>

0 comments on commit f3f2042

Please sign in to comment.