Skip to content

Commit f8a17ad

Browse files
committed
Delete old
1 parent b9d2a24 commit f8a17ad

1 file changed

Lines changed: 22 additions & 142 deletions

File tree

src/Database/Adapter/MariaDB.php

Lines changed: 22 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -988,164 +988,47 @@ public function updateDocument(Document $collection, string $id, Document $docum
988988
if (!$skipPermissions) {
989989
/**
990990
* Permission rows in the _perms table are keyed by the document's
991-
* UID (the _document column). When the UID changes, the existing
992-
* rows must be re-pointed to the new UID before the diff below is
993-
* applied, otherwise the old rows are orphaned and unchanged
994-
* permissions are lost for the new UID.
991+
* UID (the _document column). Replace the permissions with a full
992+
* rewrite: delete every existing row for the (old) UID, then
993+
* re-insert the document's current permission set under the (new)
994+
* UID. This keeps the logic simple and correctly re-keys the
995+
* permission rows when the UID changes.
995996
*/
996997
$newUid = $document->offsetExists('$id') ? $document->getId() : $id;
997-
$uidChanged = $newUid !== $id;
998998

999999
$sql = "
1000-
SELECT _type, _permission
1001-
FROM {$this->getSQLTable($name . '_perms')}
1000+
DELETE FROM {$this->getSQLTable($name . '_perms')}
10021001
WHERE _document = :_uid
10031002
{$this->getTenantQuery($collection)}
10041003
";
10051004

1006-
$sql = $this->trigger(Database::EVENT_PERMISSIONS_READ, $sql);
1005+
$sql = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $sql);
10071006

1008-
/**
1009-
* Get current permissions from the database
1010-
*/
1011-
$sqlPermissions = $this->getPDO()->prepare($sql);
1012-
1013-
$sqlPermissions->bindValue(':_uid', $id);
1007+
$stmtRemovePermissions = $this->getPDO()->prepare($sql);
1008+
$stmtRemovePermissions->bindValue(':_uid', $id);
10141009

10151010
if ($this->sharedTables) {
1016-
$sqlPermissions->bindValue(':_tenant', $this->tenant);
1017-
}
1018-
1019-
$sqlPermissions->execute();
1020-
$permissions = $sqlPermissions->fetchAll();
1021-
$sqlPermissions->closeCursor();
1022-
1023-
$initial = [];
1024-
foreach (Database::PERMISSIONS as $type) {
1025-
$initial[$type] = [];
1011+
$stmtRemovePermissions->bindValue(':_tenant', $this->tenant);
10261012
}
10271013

1028-
$permissions = array_reduce($permissions, function (array $carry, array $item) {
1029-
$carry[$item['_type']][] = $item['_permission'];
1030-
1031-
return $carry;
1032-
}, $initial);
1033-
10341014
/**
1035-
* Get removed Permissions
1015+
* Insert the document's full current permission set under the
1016+
* (new) UID.
10361017
*/
1037-
$removals = [];
1018+
$values = [];
10381019
foreach (Database::PERMISSIONS as $type) {
1039-
$diff = \array_diff($permissions[$type], $document->getPermissionsByType($type));
1040-
if (!empty($diff)) {
1041-
$removals[$type] = $diff;
1042-
}
1043-
}
1044-
1045-
/**
1046-
* Get added Permissions
1047-
*/
1048-
$additions = [];
1049-
foreach (Database::PERMISSIONS as $type) {
1050-
$diff = \array_diff($document->getPermissionsByType($type), $permissions[$type]);
1051-
if (!empty($diff)) {
1052-
$additions[$type] = $diff;
1053-
}
1054-
}
1055-
1056-
/**
1057-
* Query to re-point existing permissions to the new UID
1058-
*/
1059-
if ($uidChanged) {
1060-
$sql = "
1061-
UPDATE {$this->getSQLTable($name . '_perms')}
1062-
SET _document = :_newUid
1063-
WHERE _document = :_uid
1064-
{$this->getTenantQuery($collection)}
1065-
";
1066-
1067-
$stmtRepointPermissions = $this->getPDO()->prepare($sql);
1068-
$stmtRepointPermissions->bindValue(':_uid', $id);
1069-
$stmtRepointPermissions->bindValue(':_newUid', $newUid);
1070-
1071-
if ($this->sharedTables) {
1072-
$stmtRepointPermissions->bindValue(':_tenant', $this->tenant);
1073-
}
1074-
}
1075-
1076-
/**
1077-
* Query to remove permissions
1078-
*/
1079-
$removeQuery = '';
1080-
if (!empty($removals)) {
1081-
$removeQuery = ' AND (';
1082-
foreach ($removals as $type => $permissions) {
1083-
$removeQuery .= "(
1084-
_type = '{$type}'
1085-
AND _permission IN (" . implode(', ', \array_map(fn (string $i) => ":_remove_{$type}_{$i}", \array_keys($permissions))) . ")
1086-
)";
1087-
if ($type !== \array_key_last($removals)) {
1088-
$removeQuery .= ' OR ';
1089-
}
1020+
foreach ($document->getPermissionsByType($type) as $i => $_) {
1021+
$tenantPlaceholder = $this->sharedTables ? ', :_tenant' : '';
1022+
$values[] = "( :_uid, '{$type}', :_add_{$type}_{$i}{$tenantPlaceholder})";
10901023
}
10911024
}
1092-
if (!empty($removeQuery)) {
1093-
$removeQuery .= ')';
1094-
$sql = "
1095-
DELETE
1096-
FROM {$this->getSQLTable($name . '_perms')}
1097-
WHERE _document = :_uid
1098-
{$this->getTenantQuery($collection)}
1099-
";
11001025

1101-
$removeQuery = $sql . $removeQuery;
1102-
1103-
$removeQuery = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $removeQuery);
1104-
1105-
$stmtRemovePermissions = $this->getPDO()->prepare($removeQuery);
1106-
$stmtRemovePermissions->bindValue(':_uid', $newUid);
1107-
1108-
if ($this->sharedTables) {
1109-
$stmtRemovePermissions->bindValue(':_tenant', $this->tenant);
1110-
}
1111-
1112-
foreach ($removals as $type => $permissions) {
1113-
foreach ($permissions as $i => $permission) {
1114-
$stmtRemovePermissions->bindValue(":_remove_{$type}_{$i}", $permission);
1115-
}
1116-
}
1117-
}
1118-
1119-
/**
1120-
* Query to add permissions
1121-
*/
1122-
if (!empty($additions)) {
1123-
$values = [];
1124-
foreach ($additions as $type => $permissions) {
1125-
foreach ($permissions as $i => $_) {
1126-
$value = "( :_uid, '{$type}', :_add_{$type}_{$i}";
1127-
1128-
if ($this->sharedTables) {
1129-
$value .= ", :_tenant)";
1130-
} else {
1131-
$value .= ")";
1132-
}
1133-
1134-
$values[] = $value;
1135-
}
1136-
}
1026+
if (!empty($values)) {
1027+
$tenantColumn = $this->sharedTables ? ', _tenant' : '';
11371028

11381029
$sql = "
1139-
INSERT INTO {$this->getSQLTable($name . '_perms')} (_document, _type, _permission
1140-
";
1141-
1142-
if ($this->sharedTables) {
1143-
$sql .= ', _tenant)';
1144-
} else {
1145-
$sql .= ')';
1146-
}
1147-
1148-
$sql .= " VALUES " . \implode(', ', $values);
1030+
INSERT INTO {$this->getSQLTable($name . '_perms')} (_document, _type, _permission{$tenantColumn})
1031+
VALUES " . \implode(', ', $values);
11491032

11501033
$sql = $this->trigger(Database::EVENT_PERMISSIONS_CREATE, $sql);
11511034

@@ -1157,8 +1040,8 @@ public function updateDocument(Document $collection, string $id, Document $docum
11571040
$stmtAddPermissions->bindValue(":_tenant", $this->tenant);
11581041
}
11591042

1160-
foreach ($additions as $type => $permissions) {
1161-
foreach ($permissions as $i => $permission) {
1043+
foreach (Database::PERMISSIONS as $type) {
1044+
foreach ($document->getPermissionsByType($type) as $i => $permission) {
11621045
$stmtAddPermissions->bindValue(":_add_{$type}_{$i}", $permission);
11631046
}
11641047
}
@@ -1240,9 +1123,6 @@ public function updateDocument(Document $collection, string $id, Document $docum
12401123

12411124
$stmt->execute();
12421125

1243-
if (isset($stmtRepointPermissions)) {
1244-
$stmtRepointPermissions->execute();
1245-
}
12461126
if (isset($stmtRemovePermissions)) {
12471127
$stmtRemovePermissions->execute();
12481128
}

0 commit comments

Comments
 (0)