From 01cd39965824de860752f156a5d400c714c64361 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 | 21 +++++++------- apps/dav/lib/CardDAV/CardDavBackend.php | 37 ++++++++++++++++--------- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 348adb8327c1a..1fb5acd2eab76 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -1214,7 +1214,7 @@ public function getMultipleCalendarObjects($calendarId, array $uris, $calendarTy public function createCalendarObject($calendarId, $objectUri, $calendarData, $calendarType = self::CALENDAR_TYPE_CALENDAR) { $extraData = $this->getDenormalizedData($calendarData); - $this->atomic(function () use ($calendarId, $objectUri, $calendarData, $extraData, $calendarType) { + return $this->atomic(function () use ($calendarId, $objectUri, $calendarData, $extraData, $calendarType) { // Try to detect duplicates $qb = $this->db->getQueryBuilder(); $qb->select($qb->func()->count('*')) @@ -1308,7 +1308,7 @@ public function createCalendarObject($calendarId, $objectUri, $calendarData, $ca public function updateCalendarObject($calendarId, $objectUri, $calendarData, $calendarType = self::CALENDAR_TYPE_CALENDAR) { $extraData = $this->getDenormalizedData($calendarData); - $this->atomic(function () use ($calendarId, $objectUri, $calendarData, $extraData, $calendarType) { + return $this->atomic(function () use ($calendarId, $objectUri, $calendarData, $extraData, $calendarType) { $query = $this->db->getQueryBuilder(); $query->update('calendarobjects') ->set('calendardata', $query->createNamedParameter($calendarData, IQueryBuilder::PARAM_LOB)) @@ -2274,7 +2274,7 @@ public function getCalendarObjectById(string $principalUri, int $id): ?array { * @param int $syncLevel * @param int|null $limit * @param int $calendarType - * @return array + * @return array|null */ public function getChangesForCalendar($calendarId, $syncToken, $syncLevel, $limit = null, $calendarType = self::CALENDAR_TYPE_CALENDAR) { return $this->atomic(function () use ($calendarId, $syncToken, $syncLevel, $limit, $calendarType) { @@ -2686,10 +2686,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) @@ -2709,10 +2709,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); }