From dd2a9dcbcd84d83aa3486048a9e946d005413af2 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 14 Nov 2023 19:24:00 +0200 Subject: [PATCH 1/2] transactions --- src/Database/Adapter/MariaDB.php | 129 +++++++++++++++---------------- src/Database/Adapter/SQL.php | 2 +- 2 files changed, 63 insertions(+), 68 deletions(-) diff --git a/src/Database/Adapter/MariaDB.php b/src/Database/Adapter/MariaDB.php index 2684d84ab..ea890eb0f 100644 --- a/src/Database/Adapter/MariaDB.php +++ b/src/Database/Adapter/MariaDB.php @@ -646,6 +646,7 @@ public function deleteIndex(string $collection, string $id): bool * @throws Exception * @throws PDOException * @throws DuplicateException + * @throws \Throwable */ public function createDocument(string $collection, Document $document): Document { @@ -658,12 +659,6 @@ public function createDocument(string $collection, Document $document): Document $columns = ''; $columnNames = ''; - try { - $this->getPDO()->beginTransaction(); - } catch (PDOException $e) { - $this->getPDO()->rollBack(); - } - /** * Insert Attributes */ @@ -732,6 +727,7 @@ public function createDocument(string $collection, Document $document): Document } try { + $this->getPDO()->beginTransaction(); $stmt->execute(); $document['$internalId'] = $this->getDocument($collection, $document->getId())->getInternalId(); @@ -739,20 +735,20 @@ public function createDocument(string $collection, Document $document): Document if (isset($stmtPermissions)) { $stmtPermissions->execute(); } - } catch (PDOException $e) { + + $this->getPDO()->commit(); + } catch (\Throwable $e) { $this->getPDO()->rollBack(); - switch ($e->getCode()) { - case 1062: - case 23000: - throw new DuplicateException('Duplicated document: ' . $e->getMessage()); - default: - throw $e; + if($e instanceof PDOException) { + switch ($e->getCode()) { + case 1062: + case 23000: + throw new DuplicateException('Duplicated document: ' . $e->getMessage()); + } } - } - if (!$this->getPDO()->commit()) { - throw new DatabaseException('Failed to commit transaction'); + throw $e; } return $document; @@ -768,6 +764,7 @@ public function createDocument(string $collection, Document $document): Document * @return array * * @throws DuplicateException + * @throws \Throwable */ public function createDocuments(string $collection, array $documents, int $batchSize = Database::INSERT_BATCH_SIZE): array { @@ -775,9 +772,9 @@ public function createDocuments(string $collection, array $documents, int $batch return $documents; } - $this->getPDO()->beginTransaction(); - try { + $this->getPDO()->beginTransaction(); + $name = $this->filter($collection); $batches = \array_chunk($documents, max(1, $batchSize)); @@ -845,20 +842,22 @@ public function createDocuments(string $collection, array $documents, int $batch } } - if (!$this->getPDO()->commit()) { - throw new Exception('Failed to commit transaction'); - } - - return $documents; - - } catch (PDOException $e) { + $this->getPDO()->commit(); + } catch (\Throwable $e) { $this->getPDO()->rollBack(); - throw match ($e->getCode()) { - 1062, 23000 => new DuplicateException('Duplicated document: ' . $e->getMessage()), - default => $e, - }; + if($e instanceof PDOException) { + switch ($e->getCode()) { + case 1062: + case 23000: + throw new DuplicateException('Duplicated document: ' . $e->getMessage()); + } + } + + throw $e; } + + return $documents; } /** @@ -870,6 +869,7 @@ public function createDocuments(string $collection, array $documents, int $batch * @throws Exception * @throws PDOException * @throws DuplicateException + * @throws \Throwable */ public function updateDocument(string $collection, Document $document): Document { @@ -909,12 +909,6 @@ public function updateDocument(string $collection, Document $document): Document return $carry; }, $initial); - try { - $this->getPDO()->beginTransaction(); - } catch (PDOException $e) { - $this->getPDO()->rollBack(); - } - /** * Get removed Permissions */ @@ -1041,6 +1035,8 @@ public function updateDocument(string $collection, Document $document): Document } try { + $this->getPDO()->beginTransaction(); + $stmt->execute(); if (isset($stmtRemovePermissions)) { @@ -1049,20 +1045,21 @@ public function updateDocument(string $collection, Document $document): Document if (isset($stmtAddPermissions)) { $stmtAddPermissions->execute(); } - } catch (PDOException $e) { + + $this->getPDO()->commit(); + } + catch (\Throwable $e) { $this->getPDO()->rollBack(); - switch ($e->getCode()) { - case 1062: - case 23000: - throw new DuplicateException('Duplicated document: ' . $e->getMessage()); - default: - throw $e; + if($e instanceof PDOException) { + switch ($e->getCode()) { + case 1062: + case 23000: + throw new DuplicateException('Duplicated document: ' . $e->getMessage()); + } } - } - if (!$this->getPDO()->commit()) { - throw new DatabaseException('Failed to commit transaction'); + throw $e; } return $document; @@ -1078,6 +1075,7 @@ public function updateDocument(string $collection, Document $document): Document * @return array * * @throws DuplicateException + * @throws \Throwable */ public function updateDocuments(string $collection, array $documents, int $batchSize = Database::INSERT_BATCH_SIZE): array { @@ -1085,9 +1083,9 @@ public function updateDocuments(string $collection, array $documents, int $batch return $documents; } - $this->getPDO()->beginTransaction(); - try { + $this->getPDO()->beginTransaction(); + $name = $this->filter($collection); $batches = \array_chunk($documents, max(1, $batchSize)); @@ -1268,19 +1266,22 @@ public function updateDocuments(string $collection, array $documents, int $batch } } - if (!$this->getPDO()->commit()) { - throw new Exception('Failed to commit transaction'); - } - - return $documents; - } catch (PDOException $e) { + $this->getPDO()->commit(); + } catch (\Throwable $e) { $this->getPDO()->rollBack(); - throw match ($e->getCode()) { - 1062, 23000 => new DuplicateException('Duplicated document: ' . $e->getMessage()), - default => $e, - }; + if($e instanceof PDOException) { + switch ($e->getCode()) { + case 1062: + case 23000: + throw new DuplicateException('Duplicated document: ' . $e->getMessage()); + } + } + + throw $e; } + + return $documents; } /** @@ -1335,12 +1336,6 @@ public function deleteDocument(string $collection, string $id): bool { $name = $this->filter($collection); - try { - $this->getPDO()->beginTransaction(); - } catch (PDOException $e) { - $this->getPDO()->rollBack(); - } - $sql = " DELETE FROM {$this->getSQLTable($name)} WHERE _uid = :_uid @@ -1363,21 +1358,21 @@ public function deleteDocument(string $collection, string $id): bool $stmtPermissions->bindValue(':_uid', $id); try { + $this->getPDO()->beginTransaction(); + if (!$stmt->execute()) { throw new DatabaseException('Failed to delete document'); } if (!$stmtPermissions->execute()) { throw new DatabaseException('Failed to clean permissions'); } + + $this->getPDO()->commit(); } catch (\Throwable $th) { $this->getPDO()->rollBack(); throw new DatabaseException($th->getMessage()); } - if (!$this->getPDO()->commit()) { - throw new DatabaseException('Failed to commit transaction'); - } - return true; } diff --git a/src/Database/Adapter/SQL.php b/src/Database/Adapter/SQL.php index dff450ff7..344b74b72 100644 --- a/src/Database/Adapter/SQL.php +++ b/src/Database/Adapter/SQL.php @@ -829,7 +829,7 @@ protected function getSQLPermissionsCondition(string $collection, array $roles): { $roles = array_map(fn (string $role) => $this->getPDO()->quote($role), $roles); return "table_main._uid IN ( - SELECT distinct(_document) + SELECT _document FROM {$this->getSQLTable($collection . '_perms')} WHERE _permission IN (" . implode(', ', $roles) . ") AND _type = 'read' From a0380b0940466aec46d272e8cd6495ae32be1cd8 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 14 Nov 2023 19:29:16 +0200 Subject: [PATCH 2/2] formatting --- src/Database/Adapter/MariaDB.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Database/Adapter/MariaDB.php b/src/Database/Adapter/MariaDB.php index ea890eb0f..83c9251c6 100644 --- a/src/Database/Adapter/MariaDB.php +++ b/src/Database/Adapter/MariaDB.php @@ -1047,8 +1047,7 @@ public function updateDocument(string $collection, Document $document): Document } $this->getPDO()->commit(); - } - catch (\Throwable $e) { + } catch (\Throwable $e) { $this->getPDO()->rollBack(); if($e instanceof PDOException) {