Skip to content

Commit

Permalink
feat(cardav): support result truncation for addressbook federation
Browse files Browse the repository at this point in the history
Signed-off-by: Hamza Mahjoubi <[email protected]>
  • Loading branch information
hamza221 committed Jan 8, 2025
1 parent d4ce307 commit c7ee3ab
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 16 deletions.
3 changes: 0 additions & 3 deletions apps/dav/lib/CardDAV/AddressBook.php
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,6 @@ private function canWrite(): bool {
}

public function getChanges($syncToken, $syncLevel, $limit = null) {
if (!$syncToken && $limit) {
throw new UnsupportedLimitOnInitialSyncException();
}

return parent::getChanges($syncToken, $syncLevel, $limit);
}
Expand Down
46 changes: 41 additions & 5 deletions apps/dav/lib/CardDAV/CardDavBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -873,8 +873,29 @@ public function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel,
'modified' => [],
'deleted' => [],
];

if ($syncToken) {
if(str_starts_with($syncToken, "init_")) {
$syncValues = explode("_", $syncToken);
$lastID = $syncValues[1];
$initialSyncToken = $syncValues[2];
$qb = $this->db->getQueryBuilder();
$qb->select('id','uri')
->from('cards')
->where(
$qb->expr()->eq('addressbookid', $qb->createNamedParameter($addressBookId))
)->setMaxResults($limit);
$stmt = $qb->executeQuery();
$values = $stmt->fetchAll(\PDO::FETCH_KEY_PAIR);
$lastID = array_key_last($values);
$result['syncToken'] = 'init_'. $lastID.'_'.$initialSyncToken;
$result['added'] = array_values($values);
$stmt->closeCursor();
$result['result_truncated'] = true;
if (count($result['added']) < $limit ) {
$result['syncToken'] = $initialSyncToken;
$result['result_truncated'] = false;
}
}
else if ($syncToken) {
$qb = $this->db->getQueryBuilder();
$qb->select('uri', 'operation')
->from('addressbookchanges')
Expand All @@ -899,6 +920,8 @@ public function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel,
// last change on a node is relevant.
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
$changes[$row['uri']] = $row['operation'];
// get the last synctoken, needed in case a limit was set
$result['syncToken'] = $row['synctoken'];
}
$stmt->closeCursor();

Expand All @@ -917,14 +940,27 @@ public function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel,
}
} else {
$qb = $this->db->getQueryBuilder();
$qb->select('uri')
$qb->select('id','uri')
->from('cards')
->where(
$qb->expr()->eq('addressbookid', $qb->createNamedParameter($addressBookId))
);
// No synctoken supplied, this is the initial sync.
$stmt = $qb->executeQuery();
$result['added'] = $stmt->fetchAll(\PDO::FETCH_COLUMN);
if (is_int($limit) && $limit > 0) {
$qb->setMaxResults($limit);
$stmt = $qb->executeQuery();
$values = $stmt->fetchAll(\PDO::FETCH_KEY_PAIR);
$lastID = array_key_last($values);
if(count(array_values($values)) === $limit ){
$result['syncToken'] = 'init_'. $lastID.'_'.$currentToken;
$result['result_truncated'] = true;
}
}
else {
$stmt = $qb->executeQuery();
}
$result['added'] = array_values($values);

$stmt->closeCursor();
}
return $result;
Expand Down
9 changes: 1 addition & 8 deletions apps/dav/lib/CardDAV/SystemAddressbook.php
Original file line number Diff line number Diff line change
Expand Up @@ -211,15 +211,8 @@ public function getChild($name): Card {
$obj['carddata'] = $carddata;
}
return new Card($this->carddavBackend, $this->addressBookInfo, $obj);
}

/**
* @throws UnsupportedLimitOnInitialSyncException
*/
}
public function getChanges($syncToken, $syncLevel, $limit = null) {
if (!$syncToken && $limit) {
throw new UnsupportedLimitOnInitialSyncException();
}

if (!$this->carddavBackend instanceof SyncSupport) {
return null;
Expand Down

0 comments on commit c7ee3ab

Please sign in to comment.