From 3f8b38393e2dea938bf8f827ec62e017bd8c61f8 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Fri, 10 Feb 2023 16:19:19 +0100 Subject: [PATCH] refactor(dav-backend): Since we're in a transaction, use QB properly when incrementing synctoken Now that we're in a transaction, we can reuse the sync token's previous value without trouble, and rewrite the increment UPDATE query without dirty direct SQL. Signed-off-by: Thomas Citharel --- apps/dav/lib/CalDAV/CalDavBackend.php | 15 +++++----- apps/dav/lib/CardDAV/CardDavBackend.php | 37 ++++++++++++++++--------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 2754b72b2ebe4..ffefd4699f4e2 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -2684,10 +2684,10 @@ public function createSchedulingObject($principalUri, $objectUri, $objectData) { * @param int $calendarType * @return void */ - protected function addChange($calendarId, $objectUri, $operation, $calendarType = self::CALENDAR_TYPE_CALENDAR) { - $this->atomic(function () use ($calendarId, $objectUri, $operation, $calendarType) { - $table = $calendarType === self::CALENDAR_TYPE_CALENDAR ? 'calendars': 'calendarsubscriptions'; + protected function addChange(int $calendarId, string $objectUri, int $operation, int $calendarType = self::CALENDAR_TYPE_CALENDAR): void { + $table = $calendarType === self::CALENDAR_TYPE_CALENDAR ? 'calendars': 'calendarsubscriptions'; + $this->atomic(function () use ($calendarId, $objectUri, $operation, $calendarType, $table) { $query = $this->db->getQueryBuilder(); $query->select('synctoken') ->from($table) @@ -2707,10 +2707,11 @@ protected function addChange($calendarId, $objectUri, $operation, $calendarType ]) ->executeStatement(); - $stmt = $this->db->prepare("UPDATE `*PREFIX*$table` SET `synctoken` = `synctoken` + 1 WHERE `id` = ?"); - $stmt->execute([ - $calendarId - ]); + $query = $this->db->getQueryBuilder(); + $query->update($table) + ->set('synctoken', $query->createNamedParameter($syncToken + 1, IQueryBuilder::PARAM_INT)) + ->where($query->expr()->eq('id', $query->createNamedParameter($calendarId))) + ->executeStatement(); }, $this->db); } diff --git a/apps/dav/lib/CardDAV/CardDavBackend.php b/apps/dav/lib/CardDAV/CardDavBackend.php index 54b83ad7af895..c10cf8c90d2bf 100644 --- a/apps/dav/lib/CardDAV/CardDavBackend.php +++ b/apps/dav/lib/CardDAV/CardDavBackend.php @@ -923,20 +923,31 @@ public function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel, * @param int $operation 1 = add, 2 = modify, 3 = delete * @return void */ - protected function addChange($addressBookId, $objectUri, $operation) { + protected function addChange(int $addressBookId, string $objectUri, int $operation): void { $this->atomic(function () use ($addressBookId, $objectUri, $operation) { - $sql = 'INSERT INTO `*PREFIX*addressbookchanges`(`uri`, `synctoken`, `addressbookid`, `operation`) SELECT ?, `synctoken`, ?, ? FROM `*PREFIX*addressbooks` WHERE `id` = ?'; - $stmt = $this->db->prepare($sql); - $stmt->execute([ - $objectUri, - $addressBookId, - $operation, - $addressBookId - ]); - $stmt = $this->db->prepare('UPDATE `*PREFIX*addressbooks` SET `synctoken` = `synctoken` + 1 WHERE `id` = ?'); - $stmt->execute([ - $addressBookId - ]); + $query = $this->db->getQueryBuilder(); + $query->select('synctoken') + ->from('addressbooks') + ->where($query->expr()->eq('id', $query->createNamedParameter($addressBookId))); + $result = $query->executeQuery(); + $syncToken = (int)$result->fetchOne(); + $result->closeCursor(); + + $query = $this->db->getQueryBuilder(); + $query->insert('addressbookchanges') + ->values([ + 'uri' => $query->createNamedParameter($objectUri), + 'synctoken' => $query->createNamedParameter($syncToken), + 'addressbookid' => $query->createNamedParameter($addressBookId), + 'operation' => $query->createNamedParameter($operation), + ]) + ->executeStatement(); + + $query = $this->db->getQueryBuilder(); + $query->update('addressbooks') + ->set('synctoken', $query->createNamedParameter($syncToken + 1, IQueryBuilder::PARAM_INT)) + ->where($query->expr()->eq('id', $query->createNamedParameter($addressBookId))) + ->executeStatement(); }, $this->db); }