Skip to content

Commit

Permalink
feature #9690 Using Oracle Database as ACL storage (skolodyazhnyy)
Browse files Browse the repository at this point in the history
This PR was squashed before being merged into the 2.5-dev branch (closes #9690).

Discussion
----------

Using Oracle Database as ACL storage

Hi,

I have faced few errors when tried to use Oracle Database:

 1. Oracle return result as an array where all column names are in uppercase, so some code, where column names was in lowercase stop working
 2. Oracle gives me an error 'ORA-00933: SQL command not properly ended' for queries where 'AS' was used in FROM and JOIN instructions
 3. Oracle require strict type match in queries, so I have added string converting for object_identity_id.

Commits
-------

5f3be0e Fix Exception messages for ObjectIdentity ObjectIdentityInterface doesn't require implementing __toString method, so we need to make sure that object can be converted to string.
  • Loading branch information
fabpot committed Mar 25, 2014
2 parents f66bed7 + 5f3be0e commit d6fccdd
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 13 deletions.
26 changes: 14 additions & 12 deletions src/Symfony/Component/Security/Acl/Dbal/AclProvider.php
Expand Up @@ -194,7 +194,8 @@ public function findAcls(array $oids, array $sids = array())
foreach ($oids as $oid) {
if (!$result->contains($oid)) {
if (1 === count($oids)) {
throw new AclNotFoundException(sprintf('No ACL found for %s.', $oid));
$objectName = method_exists($oid, '__toString') ? $oid : get_class($oid);
throw new AclNotFoundException(sprintf('No ACL found for %s.', $objectName));
}

$partialResultException = new NotAllAclsFoundException('The provider could not find ACLs for all object identities.');
Expand Down Expand Up @@ -283,7 +284,8 @@ protected function getAncestorLookupSql(array $batch)
if (1 === count($types)) {
$ids = array();
for ($i = 0; $i < $count; $i++) {
$ids[] = $this->connection->quote($batch[$i]->getIdentifier());
$identifier = (string) $batch[$i]->getIdentifier();
$ids[] = $this->connection->quote($identifier);
}

$sql .= sprintf(
Expand Down Expand Up @@ -325,17 +327,17 @@ protected function getFindChildrenSql(ObjectIdentityInterface $oid, $directChild
$query = <<<FINDCHILDREN
SELECT o.object_identifier, c.class_type
FROM
{$this->options['oid_table_name']} as o
INNER JOIN {$this->options['class_table_name']} as c ON c.id = o.class_id
INNER JOIN {$this->options['oid_ancestors_table_name']} as a ON a.object_identity_id = o.id
{$this->options['oid_table_name']} o
INNER JOIN {$this->options['class_table_name']} c ON c.id = o.class_id
INNER JOIN {$this->options['oid_ancestors_table_name']} a ON a.object_identity_id = o.id
WHERE
a.ancestor_id = %d AND a.object_identity_id != a.ancestor_id
FINDCHILDREN;
} else {
$query = <<<FINDCHILDREN
SELECT o.object_identifier, c.class_type
FROM {$this->options['oid_table_name']} as o
INNER JOIN {$this->options['class_table_name']} as c ON c.id = o.class_id
FROM {$this->options['oid_table_name']} o
INNER JOIN {$this->options['class_table_name']} c ON c.id = o.class_id
WHERE o.parent_object_identity_id = %d
FINDCHILDREN;
}
Expand Down Expand Up @@ -363,8 +365,8 @@ protected function getSelectObjectIdentityIdSql(ObjectIdentityInterface $oid)
$query,
$this->options['oid_table_name'],
$this->options['class_table_name'],
$this->connection->quote($oid->getIdentifier()),
$this->connection->quote($oid->getType())
$this->connection->quote((string) $oid->getIdentifier()),
$this->connection->quote((string) $oid->getType())
);
}

Expand Down Expand Up @@ -419,8 +421,8 @@ private function getAncestorIds(array $batch)
$ancestorIds = array();
foreach ($this->connection->executeQuery($sql)->fetchAll() as $data) {
// FIXME: skip ancestors which are cached

$ancestorIds[] = $data['ancestor_id'];
// Fix: Oracle returns keys in uppercase
$ancestorIds[] = reset($data);
}

return $ancestorIds;
Expand Down Expand Up @@ -524,7 +526,7 @@ private function hydrateObjectIdentities(Statement $stmt, array $oidLookup, arra
$auditSuccess,
$auditFailure,
$username,
$securityIdentifier) = $data;
$securityIdentifier) = array_values($data);

// has the ACL been hydrated during this hydration cycle?
if (isset($acls[$aclId])) {
Expand Down
Expand Up @@ -51,7 +51,8 @@ public function __construct(Connection $connection, PermissionGrantingStrategyIn
public function createAcl(ObjectIdentityInterface $oid)
{
if (false !== $this->retrieveObjectIdentityPrimaryKey($oid)) {
throw new AclAlreadyExistsException(sprintf('%s is already associated with an ACL.', $oid));
$objectName = method_exists($oid, '__toString') ? $oid : get_class($oid);
throw new AclAlreadyExistsException(sprintf('%s is already associated with an ACL.', $objectName));
}

$this->connection->beginTransaction();
Expand Down

0 comments on commit d6fccdd

Please sign in to comment.