Skip to content

Commit

Permalink
Transactions added based on UserTransaction interface
Browse files Browse the repository at this point in the history
  • Loading branch information
Johannes Stark committed Jul 6, 2011
1 parent be5fec9 commit 1f5dd34
Show file tree
Hide file tree
Showing 4 changed files with 346 additions and 5 deletions.
16 changes: 15 additions & 1 deletion src/Jackalope/Session.php
Expand Up @@ -38,6 +38,7 @@ class Session implements \PHPCR\SessionInterface
protected $repository;
protected $workspace;
protected $objectManager;
protected $utx = null;
protected $credentials;
protected $logout = false;
/**
Expand All @@ -63,12 +64,18 @@ public function __construct($factory, Repository $repository, $workspaceName, \P
$this->factory = $factory;
$this->repository = $repository;
$this->objectManager = $this->factory->get('ObjectManager', array($transport, $this));
$this->utx = $this->factory->get('Transaction\\UserTransaction', array($transport, $this));
$this->workspace = $this->factory->get('Workspace', array($this, $this->objectManager, $workspaceName));
$this->credentials = $credentials;
$this->namespaceRegistry = $this->workspace->getNamespaceRegistry();
self::registerSession($this);
}

public function getTransactionManager()
{
return $this->utx;
}

/**
* Returns the Repository object through which this session was acquired.
*
Expand Down Expand Up @@ -458,7 +465,14 @@ public function removeItem($absPath)
*/
public function save()
{
$this->objectManager->save();
if (! $this->utx->inTransaction())
{
$this->utx->begin();
$this->objectManager->save();
$this->utx->commit();
} else {
$this->objectManager->save();
}
}

/**
Expand Down
167 changes: 167 additions & 0 deletions src/Jackalope/Transaction/UserTransaction.php
@@ -0,0 +1,167 @@
<?php

namespace Jackalope\Transaction;

use Jackalope;
use PHPCR;

/**
*
*
* @api
*/
class UserTransaction implements \PHPCR\Transaction\UserTransactionInterface
{
/**
* The factory to instantiate objects
* @var Factory
*/
protected $factory;

/**
* Instance of an implementation of the \PHPCR\SessionInterface.
* @var \PHPCR\SessionInterface
*/
protected $session;

/**
* Instance of an implementation of the TransportInterface
* @var TransportInterface
*/
protected $transport;

/**
* Stores the actual state if the application is inside a transaction or not
* @var inTransaction
*/
protected $inTransaction = false;

/**
* Registers the provided parameters as attribute to the instance.
*
* @param object $factory an object factory implementing "get" as described in \Jackalope\Factory
* @param TransportInterface $transport
* @param \PHPCR\SessionInterface $session
*/
public function __construct($factory, \Jackalope\TransportInterface $transport, \PHPCR\SessionInterface $session)
{
$this->factory = $factory;
$this->transport = $transport;
$this->session = $session;
}


/**
* Begin new transaction associated with current session.
*
* @return void
*
* @throws \PHPCR\UnsupportedRepositoryOperationException Thrown if a transaction
* is already started and the transaction implementation or backend does not
* support nested transactions.
*
* @throws \PHPCR\RepositoryException Thrown if the transaction implementation
* encounters an unexpected error condition.
*/
public function begin()
{
if ($this->inTransaction) {
throw new \PHPCR\UnsupportedRepositoryOperationException("Nested transactions are not supported.");
}

$this->transport->beginTransaction();
$this->inTransaction = true;
}

/**
*
* Complete the transaction associated with the current session.
* TODO: Make shure RollbackException and AccessDeniedException are thrown by the transport
* if corresponding problems occure
*
* @return void
*
* @throws \PHPCR\Transaction\RollbackException Thrown to indicate that the
* transaction has been rolled back rather than committed.
* @throws \PHPCR\AccessDeniedException Thrown to indicate that the
* session is not allowed to commit the transaction.
* @throws LogicException Thrown if the current
* session is not associated with a transaction.
* @throws \PHPCR\RepositoryException Thrown if the transaction implementation
* encounters an unexpected error condition.
*/
public function commit()
{
if (! $this->inTransaction) {
throw new LogicException("No transaction to commit.");
}

$this->transport->commitTransaction();
$this->inTransaction = false;
}

/**
*
* Obtain the status if the current session is inside of a transaction or not.
*
* @return boolean
*
* @throws \PHPCR\RepositoryException Thrown if the transaction implementation
* encounters an unexpected error condition.
*/
public function inTransaction()
{
//TODO Is there a way to ask for the transaction status via webdav?
return $this->inTransaction;
}

/**
*
* Roll back the transaction associated with the current session.
* TODO: Make shure AccessDeniedException is thrown by the transport
* if corresponding problems occure
*
* @return void
*
* @throws \PHPCR\AccessDeniedException Thrown to indicate that the
* application is not allowed to roll back the transaction.
* @throws LogicException Thrown if the current
* session is not associated with a transaction.
* @throws \PHPCR\RepositoryException Thrown if the transaction implementation
* encounters an unexpected error condition.
*/
public function rollback()
{
if (! $this->inTransaction) {
throw new LogicException("No transaction to rollback.");
}

$this->transport->rollbackTransaction();
$this->inTransaction = false;
$this->session->clear();
}

/**
*
* Modify the timeout value that is associated with transactions started by
* the current application with the begin method. If an application has not
* called this method, the transaction service uses some default value for the
* transaction timeout.
*
* @param int $seconds The value of the timeout in seconds. If the value is zero,
* the transaction service restores the default value. If the value is
* negative a RepositoryException is thrown.
*
* @return void
*
* @throws \PHPCR\RepositoryException Thrown if the transaction implementation
* encounters an unexpected error condition.
*/
public function setTransactionTimeout($seconds = 0)
{
if ($seconds < 0) {
throw new \PHPCR\RepositoryException("Value must be possitiv or 0. ". $seconds ." given.");
}
$this->transport->setTransactionTimeout($seconds);
}
}

0 comments on commit 1f5dd34

Please sign in to comment.