Skip to content

Commit c7ee3ab

Browse files
committed
feat(cardav): support result truncation for addressbook federation
Signed-off-by: Hamza Mahjoubi <[email protected]>
1 parent d4ce307 commit c7ee3ab

3 files changed

Lines changed: 42 additions & 16 deletions

File tree

apps/dav/lib/CardDAV/AddressBook.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,9 +234,6 @@ private function canWrite(): bool {
234234
}
235235

236236
public function getChanges($syncToken, $syncLevel, $limit = null) {
237-
if (!$syncToken && $limit) {
238-
throw new UnsupportedLimitOnInitialSyncException();
239-
}
240237

241238
return parent::getChanges($syncToken, $syncLevel, $limit);
242239
}

apps/dav/lib/CardDAV/CardDavBackend.php

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -873,8 +873,29 @@ public function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel,
873873
'modified' => [],
874874
'deleted' => [],
875875
];
876-
877-
if ($syncToken) {
876+
if(str_starts_with($syncToken, "init_")) {
877+
$syncValues = explode("_", $syncToken);
878+
$lastID = $syncValues[1];
879+
$initialSyncToken = $syncValues[2];
880+
$qb = $this->db->getQueryBuilder();
881+
$qb->select('id','uri')
882+
->from('cards')
883+
->where(
884+
$qb->expr()->eq('addressbookid', $qb->createNamedParameter($addressBookId))
885+
)->setMaxResults($limit);
886+
$stmt = $qb->executeQuery();
887+
$values = $stmt->fetchAll(\PDO::FETCH_KEY_PAIR);
888+
$lastID = array_key_last($values);
889+
$result['syncToken'] = 'init_'. $lastID.'_'.$initialSyncToken;
890+
$result['added'] = array_values($values);
891+
$stmt->closeCursor();
892+
$result['result_truncated'] = true;
893+
if (count($result['added']) < $limit ) {
894+
$result['syncToken'] = $initialSyncToken;
895+
$result['result_truncated'] = false;
896+
}
897+
}
898+
else if ($syncToken) {
878899
$qb = $this->db->getQueryBuilder();
879900
$qb->select('uri', 'operation')
880901
->from('addressbookchanges')
@@ -899,6 +920,8 @@ public function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel,
899920
// last change on a node is relevant.
900921
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
901922
$changes[$row['uri']] = $row['operation'];
923+
// get the last synctoken, needed in case a limit was set
924+
$result['syncToken'] = $row['synctoken'];
902925
}
903926
$stmt->closeCursor();
904927

@@ -917,14 +940,27 @@ public function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel,
917940
}
918941
} else {
919942
$qb = $this->db->getQueryBuilder();
920-
$qb->select('uri')
943+
$qb->select('id','uri')
921944
->from('cards')
922945
->where(
923946
$qb->expr()->eq('addressbookid', $qb->createNamedParameter($addressBookId))
924947
);
925948
// No synctoken supplied, this is the initial sync.
926-
$stmt = $qb->executeQuery();
927-
$result['added'] = $stmt->fetchAll(\PDO::FETCH_COLUMN);
949+
if (is_int($limit) && $limit > 0) {
950+
$qb->setMaxResults($limit);
951+
$stmt = $qb->executeQuery();
952+
$values = $stmt->fetchAll(\PDO::FETCH_KEY_PAIR);
953+
$lastID = array_key_last($values);
954+
if(count(array_values($values)) === $limit ){
955+
$result['syncToken'] = 'init_'. $lastID.'_'.$currentToken;
956+
$result['result_truncated'] = true;
957+
}
958+
}
959+
else {
960+
$stmt = $qb->executeQuery();
961+
}
962+
$result['added'] = array_values($values);
963+
928964
$stmt->closeCursor();
929965
}
930966
return $result;

apps/dav/lib/CardDAV/SystemAddressbook.php

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -211,15 +211,8 @@ public function getChild($name): Card {
211211
$obj['carddata'] = $carddata;
212212
}
213213
return new Card($this->carddavBackend, $this->addressBookInfo, $obj);
214-
}
215-
216-
/**
217-
* @throws UnsupportedLimitOnInitialSyncException
218-
*/
214+
}
219215
public function getChanges($syncToken, $syncLevel, $limit = null) {
220-
if (!$syncToken && $limit) {
221-
throw new UnsupportedLimitOnInitialSyncException();
222-
}
223216

224217
if (!$this->carddavBackend instanceof SyncSupport) {
225218
return null;

0 commit comments

Comments
 (0)