Merge pull request #21733 from nextcloud/fix/noid/cache-system-card-etag-during-request

Update system addressbook card only when there was a change based on a cached etag
This commit is contained in:
Morris Jobke 2020-07-09 13:59:24 +02:00 committed by GitHub
commit 18acb137d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 4 deletions

View File

@ -90,6 +90,8 @@ class CardDavBackend implements BackendInterface, SyncSupport {
/** @var EventDispatcherInterface */ /** @var EventDispatcherInterface */
private $dispatcher; private $dispatcher;
private $etagCache = [];
/** /**
* CardDavBackend constructor. * CardDavBackend constructor.
* *
@ -653,6 +655,9 @@ class CardDavBackend implements BackendInterface, SyncSupport {
]) ])
->execute(); ->execute();
$etagCacheKey = "$addressBookId#$cardUri";
$this->etagCache[$etagCacheKey] = $etag;
$this->addChange($addressBookId, $cardUri, 1); $this->addChange($addressBookId, $cardUri, 1);
$this->updateProperties($addressBookId, $cardUri, $cardData); $this->updateProperties($addressBookId, $cardUri, $cardData);
@ -694,6 +699,13 @@ class CardDavBackend implements BackendInterface, SyncSupport {
$uid = $this->getUID($cardData); $uid = $this->getUID($cardData);
$etag = md5($cardData); $etag = md5($cardData);
$query = $this->db->getQueryBuilder(); $query = $this->db->getQueryBuilder();
// check for recently stored etag and stop if it is the same
$etagCacheKey = "$addressBookId#$cardUri";
if (isset($this->etagCache[$etagCacheKey]) && $this->etagCache[$etagCacheKey] === $etag) {
return '"' . $etag . '"';
}
$query->update($this->dbCardsTable) $query->update($this->dbCardsTable)
->set('carddata', $query->createNamedParameter($cardData, IQueryBuilder::PARAM_LOB)) ->set('carddata', $query->createNamedParameter($cardData, IQueryBuilder::PARAM_LOB))
->set('lastmodified', $query->createNamedParameter(time())) ->set('lastmodified', $query->createNamedParameter(time()))
@ -704,6 +716,8 @@ class CardDavBackend implements BackendInterface, SyncSupport {
->andWhere($query->expr()->eq('addressbookid', $query->createNamedParameter($addressBookId))) ->andWhere($query->expr()->eq('addressbookid', $query->createNamedParameter($addressBookId)))
->execute(); ->execute();
$this->etagCache[$etagCacheKey] = $etag;
$this->addChange($addressBookId, $cardUri, 2); $this->addChange($addressBookId, $cardUri, 2);
$this->updateProperties($addressBookId, $cardUri, $cardData); $this->updateProperties($addressBookId, $cardUri, $cardData);

View File

@ -253,7 +253,7 @@ class CardDavBackendTest extends TestCase {
$uri = $this->getUniqueID('card'); $uri = $this->getUniqueID('card');
// updateProperties is expected twice, once for createCard and once for updateCard // updateProperties is expected twice, once for createCard and once for updateCard
$backend->expects($this->at(0))->method('updateProperties')->with($bookId, $uri, $this->vcardTest0); $backend->expects($this->at(0))->method('updateProperties')->with($bookId, $uri, $this->vcardTest0);
$backend->expects($this->at(1))->method('updateProperties')->with($bookId, $uri, $this->vcardTest0); $backend->expects($this->at(1))->method('updateProperties')->with($bookId, $uri, $this->vcardTest1);
// Expect event // Expect event
$this->dispatcher->expects($this->at(0)) $this->dispatcher->expects($this->at(0))
@ -288,13 +288,13 @@ class CardDavBackendTest extends TestCase {
->with('\OCA\DAV\CardDAV\CardDavBackend::updateCard', $this->callback(function (GenericEvent $e) use ($bookId, $uri) { ->with('\OCA\DAV\CardDAV\CardDavBackend::updateCard', $this->callback(function (GenericEvent $e) use ($bookId, $uri) {
return $e->getArgument('addressBookId') === $bookId && return $e->getArgument('addressBookId') === $bookId &&
$e->getArgument('cardUri') === $uri && $e->getArgument('cardUri') === $uri &&
$e->getArgument('cardData') === $this->vcardTest0; $e->getArgument('cardData') === $this->vcardTest1;
})); }));
// update the card // update the card
$backend->updateCard($bookId, $uri, $this->vcardTest0); $backend->updateCard($bookId, $uri, $this->vcardTest1);
$card = $backend->getCard($bookId, $uri); $card = $backend->getCard($bookId, $uri);
$this->assertEquals($this->vcardTest0, $card['carddata']); $this->assertEquals($this->vcardTest1, $card['carddata']);
// Expect event // Expect event
$this->dispatcher->expects($this->at(0)) $this->dispatcher->expects($this->at(0))