Skip to content

Commit cfba533

Browse files
authored
Merge pull request #891 from utopia-php/bug-update-document-uid-with-delete
Bug update document uid with delete
2 parents 6989524 + e6cb341 commit cfba533

5 files changed

Lines changed: 185 additions & 343 deletions

File tree

src/Database/Adapter/MariaDB.php

Lines changed: 23 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -980,155 +980,55 @@ public function updateDocument(Document $collection, string $id, Document $docum
980980
$attributes['_createdAt'] = $document->getCreatedAt();
981981
$attributes['_updatedAt'] = $document->getUpdatedAt();
982982
$attributes['_permissions'] = json_encode($document->getPermissions());
983+
$attributes['_uid'] = $document->getId();
983984

984985
$name = $this->filter($collection);
985986
$columns = '';
986987

987988
if (!$skipPermissions) {
989+
$newUid = $document->offsetExists('$id') ? $document->getId() : $id;
990+
988991
$sql = "
989-
SELECT _type, _permission
990-
FROM {$this->getSQLTable($name . '_perms')}
992+
DELETE FROM {$this->getSQLTable($name . '_perms')}
991993
WHERE _document = :_uid
992994
{$this->getTenantQuery($collection)}
993-
";
995+
";
994996

995-
$sql = $this->trigger(Database::EVENT_PERMISSIONS_READ, $sql);
996-
997-
/**
998-
* Get current permissions from the database
999-
*/
1000-
$sqlPermissions = $this->getPDO()->prepare($sql);
1001-
$sqlPermissions->bindValue(':_uid', $document->getId());
997+
$sql = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $sql);
1002998

999+
$stmtRemovePermissions = $this->getPDO()->prepare($sql);
1000+
$stmtRemovePermissions->bindValue(':_uid', $id);
10031001
if ($this->sharedTables) {
1004-
$sqlPermissions->bindValue(':_tenant', $this->tenant);
1002+
$stmtRemovePermissions->bindValue(':_tenant', $this->tenant);
10051003
}
10061004

1007-
$sqlPermissions->execute();
1008-
$permissions = $sqlPermissions->fetchAll();
1009-
$sqlPermissions->closeCursor();
1010-
1011-
$initial = [];
1012-
foreach (Database::PERMISSIONS as $type) {
1013-
$initial[$type] = [];
1014-
}
1015-
1016-
$permissions = array_reduce($permissions, function (array $carry, array $item) {
1017-
$carry[$item['_type']][] = $item['_permission'];
1018-
1019-
return $carry;
1020-
}, $initial);
1021-
1022-
/**
1023-
* Get removed Permissions
1024-
*/
1025-
$removals = [];
1005+
$values = [];
1006+
$binds = [];
10261007
foreach (Database::PERMISSIONS as $type) {
1027-
$diff = \array_diff($permissions[$type], $document->getPermissionsByType($type));
1028-
if (!empty($diff)) {
1029-
$removals[$type] = $diff;
1030-
}
1031-
}
1032-
1033-
/**
1034-
* Get added Permissions
1035-
*/
1036-
$additions = [];
1037-
foreach (Database::PERMISSIONS as $type) {
1038-
$diff = \array_diff($document->getPermissionsByType($type), $permissions[$type]);
1039-
if (!empty($diff)) {
1040-
$additions[$type] = $diff;
1041-
}
1042-
}
1043-
1044-
/**
1045-
* Query to remove permissions
1046-
*/
1047-
$removeQuery = '';
1048-
if (!empty($removals)) {
1049-
$removeQuery = ' AND (';
1050-
foreach ($removals as $type => $permissions) {
1051-
$removeQuery .= "(
1052-
_type = '{$type}'
1053-
AND _permission IN (" . implode(', ', \array_map(fn (string $i) => ":_remove_{$type}_{$i}", \array_keys($permissions))) . ")
1054-
)";
1055-
if ($type !== \array_key_last($removals)) {
1056-
$removeQuery .= ' OR ';
1057-
}
1008+
foreach ($document->getPermissionsByType($type) as $i => $permission) {
1009+
$tenantPlaceholder = $this->sharedTables ? ', :_tenant' : '';
1010+
$values[] = "( :_uid, '{$type}', :_add_{$type}_{$i} {$tenantPlaceholder})";
1011+
$binds[":_add_{$type}_{$i}"] = $permission;
10581012
}
10591013
}
1060-
if (!empty($removeQuery)) {
1061-
$removeQuery .= ')';
1062-
$sql = "
1063-
DELETE
1064-
FROM {$this->getSQLTable($name . '_perms')}
1065-
WHERE _document = :_uid
1066-
{$this->getTenantQuery($collection)}
1067-
";
1068-
1069-
$removeQuery = $sql . $removeQuery;
10701014

1071-
$removeQuery = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $removeQuery);
1072-
1073-
$stmtRemovePermissions = $this->getPDO()->prepare($removeQuery);
1074-
$stmtRemovePermissions->bindValue(':_uid', $document->getId());
1075-
1076-
if ($this->sharedTables) {
1077-
$stmtRemovePermissions->bindValue(':_tenant', $this->tenant);
1078-
}
1079-
1080-
foreach ($removals as $type => $permissions) {
1081-
foreach ($permissions as $i => $permission) {
1082-
$stmtRemovePermissions->bindValue(":_remove_{$type}_{$i}", $permission);
1083-
}
1084-
}
1085-
}
1086-
1087-
/**
1088-
* Query to add permissions
1089-
*/
1090-
if (!empty($additions)) {
1091-
$values = [];
1092-
foreach ($additions as $type => $permissions) {
1093-
foreach ($permissions as $i => $_) {
1094-
$value = "( :_uid, '{$type}', :_add_{$type}_{$i}";
1095-
1096-
if ($this->sharedTables) {
1097-
$value .= ", :_tenant)";
1098-
} else {
1099-
$value .= ")";
1100-
}
1101-
1102-
$values[] = $value;
1103-
}
1104-
}
1015+
if (!empty($values)) {
1016+
$tenantColumn = $this->sharedTables ? ', _tenant' : '';
11051017

11061018
$sql = "
1107-
INSERT INTO {$this->getSQLTable($name . '_perms')} (_document, _type, _permission
1108-
";
1109-
1110-
if ($this->sharedTables) {
1111-
$sql .= ', _tenant)';
1112-
} else {
1113-
$sql .= ')';
1114-
}
1115-
1116-
$sql .= " VALUES " . \implode(', ', $values);
1019+
INSERT INTO {$this->getSQLTable($name . '_perms')} (_document, _type, _permission {$tenantColumn})
1020+
VALUES " . \implode(', ', $values);
11171021

11181022
$sql = $this->trigger(Database::EVENT_PERMISSIONS_CREATE, $sql);
11191023

11201024
$stmtAddPermissions = $this->getPDO()->prepare($sql);
1121-
1122-
$stmtAddPermissions->bindValue(":_uid", $document->getId());
1123-
1025+
$stmtAddPermissions->bindValue(":_uid", $newUid);
11241026
if ($this->sharedTables) {
11251027
$stmtAddPermissions->bindValue(":_tenant", $this->tenant);
11261028
}
11271029

1128-
foreach ($additions as $type => $permissions) {
1129-
foreach ($permissions as $i => $permission) {
1130-
$stmtAddPermissions->bindValue(":_add_{$type}_{$i}", $permission);
1131-
}
1030+
foreach ($binds as $key => $permission) {
1031+
$stmtAddPermissions->bindValue($key, $permission);
11321032
}
11331033
}
11341034
}
@@ -1168,7 +1068,7 @@ public function updateDocument(Document $collection, string $id, Document $docum
11681068

11691069
$sql = "
11701070
UPDATE {$this->getSQLTable($name)}
1171-
SET {$columns} _uid = :_newUid
1071+
SET " . \rtrim($columns, ',') . "
11721072
WHERE _id=:_sequence
11731073
{$this->getTenantQuery($collection)}
11741074
";
@@ -1178,7 +1078,6 @@ public function updateDocument(Document $collection, string $id, Document $docum
11781078
$stmt = $this->getPDO()->prepare($sql);
11791079

11801080
$stmt->bindValue(':_sequence', $document->getSequence());
1181-
$stmt->bindValue(':_newUid', $document->getId());
11821081

11831082
if ($this->sharedTables) {
11841083
$stmt->bindValue(':_tenant', $this->tenant);

src/Database/Adapter/Postgres.php

Lines changed: 20 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,140 +1139,55 @@ public function updateDocument(Document $collection, string $id, Document $docum
11391139
$attributes['_createdAt'] = $document->getCreatedAt();
11401140
$attributes['_updatedAt'] = $document->getUpdatedAt();
11411141
$attributes['_permissions'] = json_encode($document->getPermissions());
1142+
$attributes['_uid'] = $document->getId();
11421143

11431144
$name = $this->filter($collection);
11441145
$columns = '';
11451146

11461147
if (!$skipPermissions) {
1148+
$newUid = $document->offsetExists('$id') ? $document->getId() : $id;
1149+
11471150
$sql = "
1148-
SELECT _type, _permission
1149-
FROM {$this->getSQLTable($name . '_perms')}
1151+
DELETE FROM {$this->getSQLTable($name . '_perms')}
11501152
WHERE _document = :_uid
11511153
{$this->getTenantQuery($collection)}
11521154
";
11531155

1154-
$sql = $this->trigger(Database::EVENT_PERMISSIONS_READ, $sql);
1155-
1156-
/**
1157-
* Get current permissions from the database
1158-
*/
1159-
$permissionsStmt = $this->getPDO()->prepare($sql);
1160-
$permissionsStmt->bindValue(':_uid', $document->getId());
1156+
$sql = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $sql);
11611157

1158+
$stmtRemovePermissions = $this->getPDO()->prepare($sql);
1159+
$stmtRemovePermissions->bindValue(':_uid', $id);
11621160
if ($this->sharedTables) {
1163-
$permissionsStmt->bindValue(':_tenant', $this->tenant);
1161+
$stmtRemovePermissions->bindValue(':_tenant', $this->tenant);
11641162
}
11651163

1166-
$this->execute($permissionsStmt);
1167-
$permissions = $permissionsStmt->fetchAll();
1168-
$permissionsStmt->closeCursor();
1169-
1170-
$initial = [];
1164+
$values = [];
1165+
$binds = [];
11711166
foreach (Database::PERMISSIONS as $type) {
1172-
$initial[$type] = [];
1173-
}
1174-
1175-
$permissions = array_reduce($permissions, function (array $carry, array $item) {
1176-
$carry[$item['_type']][] = $item['_permission'];
1177-
1178-
return $carry;
1179-
}, $initial);
1180-
1181-
/**
1182-
* Get removed Permissions
1183-
*/
1184-
$removals = [];
1185-
foreach (Database::PERMISSIONS as $type) {
1186-
$diff = \array_diff($permissions[$type], $document->getPermissionsByType($type));
1187-
if (!empty($diff)) {
1188-
$removals[$type] = $diff;
1189-
}
1190-
}
1191-
1192-
/**
1193-
* Get added Permissions
1194-
*/
1195-
$additions = [];
1196-
foreach (Database::PERMISSIONS as $type) {
1197-
$diff = \array_diff($document->getPermissionsByType($type), $permissions[$type]);
1198-
if (!empty($diff)) {
1199-
$additions[$type] = $diff;
1200-
}
1201-
}
1202-
1203-
/**
1204-
* Query to remove permissions
1205-
*/
1206-
$removeQuery = '';
1207-
if (!empty($removals)) {
1208-
$removeQuery = ' AND (';
1209-
foreach ($removals as $type => $permissions) {
1210-
$removeQuery .= "(
1211-
_type = '{$type}'
1212-
AND _permission IN (" . implode(', ', \array_map(fn (string $i) => ":_remove_{$type}_{$i}", \array_keys($permissions))) . ")
1213-
)";
1214-
if ($type !== \array_key_last($removals)) {
1215-
$removeQuery .= ' OR ';
1216-
}
1167+
foreach ($document->getPermissionsByType($type) as $i => $permission) {
1168+
$sqlTenant = $this->sharedTables ? ', :_tenant' : '';
1169+
$values[] = "( :_uid, '{$type}', :_add_{$type}_{$i} {$sqlTenant})";
1170+
$binds[":_add_{$type}_{$i}"] = $permission;
12171171
}
12181172
}
1219-
if (!empty($removeQuery)) {
1220-
$removeQuery .= ')';
1221-
1222-
$sql = "
1223-
DELETE
1224-
FROM {$this->getSQLTable($name . '_perms')}
1225-
WHERE _document = :_uid
1226-
{$this->getTenantQuery($collection)}
1227-
";
1228-
1229-
$removeQuery = $sql . $removeQuery;
1230-
1231-
$removeQuery = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $removeQuery);
1232-
$stmtRemovePermissions = $this->getPDO()->prepare($removeQuery);
1233-
$stmtRemovePermissions->bindValue(':_uid', $document->getId());
1234-
1235-
if ($this->sharedTables) {
1236-
$stmtRemovePermissions->bindValue(':_tenant', $this->tenant);
1237-
}
1238-
1239-
foreach ($removals as $type => $permissions) {
1240-
foreach ($permissions as $i => $permission) {
1241-
$stmtRemovePermissions->bindValue(":_remove_{$type}_{$i}", $permission);
1242-
}
1243-
}
1244-
}
1245-
1246-
/**
1247-
* Query to add permissions
1248-
*/
1249-
if (!empty($additions)) {
1250-
$values = [];
1251-
foreach ($additions as $type => $permissions) {
1252-
foreach ($permissions as $i => $_) {
1253-
$sqlTenant = $this->sharedTables ? ', :_tenant' : '';
1254-
$values[] = "( :_uid, '{$type}', :_add_{$type}_{$i} {$sqlTenant})";
1255-
}
1256-
}
12571173

1174+
if (!empty($values)) {
12581175
$sqlTenant = $this->sharedTables ? ', _tenant' : '';
12591176

12601177
$sql = "
12611178
INSERT INTO {$this->getSQLTable($name . '_perms')} (_document, _type, _permission {$sqlTenant})
1262-
VALUES" . \implode(', ', $values);
1179+
VALUES " . \implode(', ', $values);
12631180

12641181
$sql = $this->trigger(Database::EVENT_PERMISSIONS_CREATE, $sql);
12651182

12661183
$stmtAddPermissions = $this->getPDO()->prepare($sql);
1267-
$stmtAddPermissions->bindValue(":_uid", $document->getId());
1184+
$stmtAddPermissions->bindValue(":_uid", $newUid);
12681185
if ($this->sharedTables) {
12691186
$stmtAddPermissions->bindValue(':_tenant', $this->tenant);
12701187
}
12711188

1272-
foreach ($additions as $type => $permissions) {
1273-
foreach ($permissions as $i => $permission) {
1274-
$stmtAddPermissions->bindValue(":_add_{$type}_{$i}", $permission);
1275-
}
1189+
foreach ($binds as $key => $permission) {
1190+
$stmtAddPermissions->bindValue($key, $permission);
12761191
}
12771192
}
12781193
}
@@ -1312,7 +1227,7 @@ public function updateDocument(Document $collection, string $id, Document $docum
13121227

13131228
$sql = "
13141229
UPDATE {$this->getSQLTable($name)}
1315-
SET {$columns} _uid = :_newUid
1230+
SET " . \rtrim($columns, ',') . "
13161231
WHERE _id=:_sequence
13171232
{$this->getTenantQuery($collection)}
13181233
";
@@ -1322,7 +1237,6 @@ public function updateDocument(Document $collection, string $id, Document $docum
13221237
$stmt = $this->getPDO()->prepare($sql);
13231238

13241239
$stmt->bindValue(':_sequence', $document->getSequence());
1325-
$stmt->bindValue(':_newUid', $document->getId());
13261240

13271241
if ($this->sharedTables) {
13281242
$stmt->bindValue(':_tenant', $this->tenant);

0 commit comments

Comments
 (0)