Skip to content

Commit 1989027

Browse files
committed
fix(carddav): return correct sync token for non-truncated requests
Signed-off-by: Daniel Kesselberg <mail@danielkesselberg.de>
1 parent a0ffc60 commit 1989027

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

apps/dav/lib/CardDAV/CardDavBackend.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -920,18 +920,20 @@ public function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel,
920920

921921
// Fetching all changes
922922
$stmt = $qb->executeQuery();
923+
$rowCount = $stmt->rowCount();
923924

924925
$changes = [];
926+
$highestSyncToken = 0;
925927

926928
// This loop ensures that any duplicates are overwritten, only the
927929
// last change on a node is relevant.
928930
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
929931
$changes[$row['uri']] = $row['operation'];
930-
// get the last synctoken, needed in case a limit was set
931-
$result['syncToken'] = $row['synctoken'];
932+
$highestSyncToken = $row['synctoken'];
932933
}
934+
933935
$stmt->closeCursor();
934-
936+
935937
// No changes found, use current token
936938
if (empty($changes)) {
937939
$result['syncToken'] = $currentToken;
@@ -950,6 +952,20 @@ public function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel,
950952
break;
951953
}
952954
}
955+
956+
/*
957+
* The synctoken in oc_addressbooks is always the highest synctoken in oc_addressbookchanges for a given addressbook plus one (see addChange).
958+
*
959+
* For truncated results, it is expected that we return the highest token from the response, so the client can continue from the latest change.
960+
*
961+
* For non-truncated results, it is expected to return the currentToken. If we return the highest token, as with truncated results, the client will always think it is one change behind.
962+
*
963+
* Therefore, we differentiate between truncated and non-truncated results when returning the synctoken.
964+
*/
965+
if ($rowCount === $limit && $highestSyncToken < $currentToken) {
966+
$result['syncToken'] = $highestSyncToken;
967+
$result['result_truncated'] = true;
968+
}
953969
} else {
954970
$qb = $this->db->getQueryBuilder();
955971
$qb->select('id', 'uri')

0 commit comments

Comments
 (0)