Skip to content

Commit

Permalink
Merge pull request #286 from jackalope/cached_client_fixes
Browse files Browse the repository at this point in the history
Cached client fixes
  • Loading branch information
lsmith77 committed Jun 25, 2015
2 parents d35b92d + 66d93af commit d80439e
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 48 deletions.
40 changes: 20 additions & 20 deletions src/Jackalope/Transport/DoctrineDBAL/CachedClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,35 +84,35 @@ protected function workspaceExists($workspaceName)
public function getNodeTypes($nodeTypes = array())
{
$cacheKey = 'nodetypes: '.serialize($nodeTypes);
$nodeTypes = $this->caches['meta']->fetch($cacheKey);
if (!$nodeTypes) {
$nodeTypes = parent::getNodeTypes($nodeTypes);
$this->caches['meta']->save($cacheKey, $nodeTypes);
$result = $this->caches['meta']->fetch($cacheKey);
if (!$result) {
$result = parent::getNodeTypes($nodeTypes);
$this->caches['meta']->save($cacheKey, $result);
}

return $nodeTypes;
return $result;
}

/**
* Return the namespaces of the current session as a referenceable ArrayObject.
*
* @return \ArrayObject
* {@inheritDoc}
*/
protected function getNamespacesObject()
public function getNamespaces()
{
if ($this->namespaces->count() === 0) {
$cacheKey = 'namespaces';
$result = $this->caches['meta']->fetch($cacheKey);
if ($result) {
$this->namespaces = $result;
} else {
$this->namespaces = parent::getNamespacesObject();

$this->caches['meta']->save($cacheKey, $this->namespaces);
}
if ($this->namespaces instanceof \ArrayObject) {
return parent::getNamespaces();
}

return $this->namespaces;
$cacheKey = 'namespaces';
$result = $this->caches['meta']->fetch($cacheKey);
if ($result) {
$this->setNamespaces($result);
} else {
$result = parent::getNamespaces();

$this->caches['meta']->save($cacheKey, $result);
}

return $result;
}

/**
Expand Down
121 changes: 93 additions & 28 deletions src/Jackalope/Transport/DoctrineDBAL/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,30 @@ class Client extends BaseTransport implements QueryTransport, WritingInterface,
private $checkLoginOnServer = true;

/**
* @var \ArrayObject
* Using an ArrayObject here so that we can pass this into the NodeProcessor by reference more elegantly
*
* @var null|\ArrayObject
*/
protected $namespaces;

/**
* @var array The namespaces at initial state, in case of rollback.
* @var null|array The namespaces at initial state when making changes to the namespaces, in case of rollback.
*/
private $originalNamespaces;

/**
* The core namespaces defined in JCR
*
* @var array
*/
private $originalNamespaces = array();
private $coreNamespaces = array(
NamespaceRegistryInterface::PREFIX_EMPTY => NamespaceRegistryInterface::NAMESPACE_EMPTY,
NamespaceRegistryInterface::PREFIX_JCR => NamespaceRegistryInterface::NAMESPACE_JCR,
NamespaceRegistryInterface::PREFIX_NT => NamespaceRegistryInterface::NAMESPACE_NT,
NamespaceRegistryInterface::PREFIX_MIX => NamespaceRegistryInterface::NAMESPACE_MIX,
NamespaceRegistryInterface::PREFIX_XML => NamespaceRegistryInterface::NAMESPACE_XML,
NamespaceRegistryInterface::PREFIX_SV => NamespaceRegistryInterface::NAMESPACE_SV,
);

/**
* @var string|null
Expand Down Expand Up @@ -186,7 +202,6 @@ public function __construct(FactoryInterface $factory, Connection $conn)
$this->factory = $factory;
$this->valueConverter = $this->factory->get('PHPCR\Util\ValueConverter');
$this->conn = $conn;
$this->namespaces = new \ArrayObject();
}

/**
Expand Down Expand Up @@ -504,6 +519,11 @@ public function getRepositoryDescriptors()
);
}

/**
* Get the registered namespace prefixes
*
* @return array
*/
private function getNamespacePrefixes()
{
return array_keys($this->getNamespaces());
Expand All @@ -524,29 +544,32 @@ public function getNamespaces()
*/
protected function getNamespacesObject()
{
if ($this->namespaces->count() === 0) {
$query = 'SELECT * FROM phpcr_namespaces';
$data = $this->getConnection()->fetchAll($query);

$this->namespaces->exchangeArray(array(
NamespaceRegistryInterface::PREFIX_EMPTY => NamespaceRegistryInterface::NAMESPACE_EMPTY,
NamespaceRegistryInterface::PREFIX_JCR => NamespaceRegistryInterface::NAMESPACE_JCR,
NamespaceRegistryInterface::PREFIX_NT => NamespaceRegistryInterface::NAMESPACE_NT,
NamespaceRegistryInterface::PREFIX_MIX => NamespaceRegistryInterface::NAMESPACE_MIX,
NamespaceRegistryInterface::PREFIX_XML => NamespaceRegistryInterface::NAMESPACE_XML,
NamespaceRegistryInterface::PREFIX_SV => NamespaceRegistryInterface::NAMESPACE_SV,
));

foreach ($data as $row) {
$this->namespaces[$row['prefix']] = $row['uri'];
}
if (null === $this->namespaces) {
$query = 'SELECT prefix, uri FROM phpcr_namespaces';
$result = $this->getConnection()->query($query);
$namespaces = (array) $result->fetchAll(\PDO::FETCH_KEY_PAIR);
$namespaces += $this->coreNamespaces;

$this->originalNamespaces = $this->namespaces;
$this->setNamespaces($namespaces);
}

return $this->namespaces;
}

/**
* Set the namespaces property to an \ArrayObject instance
*
* @param array $namespaces
*/
protected function setNamespaces(array $namespaces)
{
if ($this->namespaces instanceof \ArrayObject) {
$this->namespaces->exchangeArray($namespaces);
} else {
$this->namespaces = new \ArrayObject($namespaces);
}
}

/**
* Executes an UPDATE on DBAL while ensuring that we never try to send more than 999 parameters to SQLite
*
Expand Down Expand Up @@ -2353,15 +2376,45 @@ public function getSupportedQueryLanguages()
);
}

/**
* We need to create an in memory backup when we are inside a transaction
* so that we can efficiently restore the original state in the namespaces
* property in case of a rollback.
*
* This method also ensures that namespaces are loaded to begin with.
*/
private function ensureNamespacesBackup()
{
if (!$this->namespaces instanceof \ArrayObject) {
$this->getNamespacesObject();
}

if (!$this->inTransaction) {
return;
}

if (null === $this->originalNamespaces) {
$this->originalNamespaces = $this->namespaces->getArrayCopy();
}
}

/**
* {@inheritDoc}
*/
public function registerNamespace($prefix, $uri)
{
if (isset($this->namespaces[$prefix]) && $this->namespaces[$prefix] === $uri) {
return;
if (isset($this->namespaces[$prefix])) {
if ($this->namespaces[$prefix] === $uri) {
return;
}

if (isset($this->coreNamespaces[$prefix])) {
throw new NamespaceException("Cannot overwrite JCR core namespace prefix '$prefix' to a new uri '$uri'.");
}
}

$this->ensureNamespacesBackup();

$this->getConnection()->delete('phpcr_namespaces', array('prefix' => $prefix));
$this->getConnection()->delete('phpcr_namespaces', array('uri' => $uri));

Expand All @@ -2380,6 +2433,12 @@ public function registerNamespace($prefix, $uri)
*/
public function unregisterNamespace($prefix)
{
if (isset($this->coreNamespaces[$prefix])) {
throw new NamespaceException("Cannot unregister JCR core namespace prefix '$prefix'.");
}

$this->ensureNamespacesBackup();

$this->getConnection()->delete('phpcr_namespaces', array('prefix' => $prefix));

if (!empty($this->namespaces)) {
Expand Down Expand Up @@ -2463,8 +2522,11 @@ public function commitTransaction()
$this->inTransaction = false;

$this->getConnection()->commit();
// now that the transaction is committed, update the cache of the stored namespaces.
$this->originalNamespaces = (array) $this->namespaces;

if ($this->originalNamespaces) {
// now that the transaction is committed, reset the cache of the stored namespaces.
$this->originalNamespaces = null;
}
} catch (\Exception $e) {
throw new RepositoryException('Commit transaction failed: ' . $e->getMessage());
}
Expand All @@ -2484,10 +2546,13 @@ public function rollbackTransaction()
try {
$this->inTransaction = false;

// reset namespaces
$this->namespaces->exchangeArray($this->originalNamespaces);

$this->getConnection()->rollback();

if ($this->originalNamespaces) {
// reset namespaces
$this->setNamespaces($this->originalNamespaces);
$this->originalNamespaces = null;
}
} catch (\Exception $e) {
throw new RepositoryException('Rollback transaction failed: ' . $e->getMessage(), 0, $e);
}
Expand Down

0 comments on commit d80439e

Please sign in to comment.