Skip to content

Commit

Permalink
Merge pull request #30863 from nextcloud/performance/saving-user-prof…
Browse files Browse the repository at this point in the history
…ile-info

Minor optimizations for saving user personal information
  • Loading branch information
CarlSchwan authored May 13, 2022
2 parents fe33e9c + e71db40 commit 9fcf531
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 47 deletions.
61 changes: 36 additions & 25 deletions apps/dav/lib/CardDAV/CardDavBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -648,23 +648,26 @@ public function getMultipleCards($addressBookId, array $uris) {
* @param mixed $addressBookId
* @param string $cardUri
* @param string $cardData
* @param bool $checkAlreadyExists
* @return string
*/
public function createCard($addressBookId, $cardUri, $cardData) {
public function createCard($addressBookId, $cardUri, $cardData, bool $checkAlreadyExists = true) {
$etag = md5($cardData);
$uid = $this->getUID($cardData);

$q = $this->db->getQueryBuilder();
$q->select('uid')
->from($this->dbCardsTable)
->where($q->expr()->eq('addressbookid', $q->createNamedParameter($addressBookId)))
->andWhere($q->expr()->eq('uid', $q->createNamedParameter($uid)))
->setMaxResults(1);
$result = $q->execute();
$count = (bool)$result->fetchOne();
$result->closeCursor();
if ($count) {
throw new \Sabre\DAV\Exception\BadRequest('VCard object with uid already exists in this addressbook collection.');
if ($checkAlreadyExists) {
$q = $this->db->getQueryBuilder();
$q->select('uid')
->from($this->dbCardsTable)
->where($q->expr()->eq('addressbookid', $q->createNamedParameter($addressBookId)))
->andWhere($q->expr()->eq('uid', $q->createNamedParameter($uid)))
->setMaxResults(1);
$result = $q->executeQuery();
$count = (bool)$result->fetchOne();
$result->closeCursor();
if ($count) {
throw new \Sabre\DAV\Exception\BadRequest('VCard object with uid already exists in this addressbook collection.');
}
}

$query = $this->db->getQueryBuilder();
Expand Down Expand Up @@ -1268,21 +1271,29 @@ protected function updateProperties($addressBookId, $cardUri, $vCardSerialized)
]
);

foreach ($vCard->children() as $property) {
if (!in_array($property->name, self::$indexProperties)) {
continue;
}
$preferred = 0;
foreach ($property->parameters as $parameter) {
if ($parameter->name === 'TYPE' && strtoupper($parameter->getValue()) === 'PREF') {
$preferred = 1;
break;

$this->db->beginTransaction();

try {
foreach ($vCard->children() as $property) {
if (!in_array($property->name, self::$indexProperties)) {
continue;
}
$preferred = 0;
foreach ($property->parameters as $parameter) {
if ($parameter->name === 'TYPE' && strtoupper($parameter->getValue()) === 'PREF') {
$preferred = 1;
break;
}
}
$query->setParameter('name', $property->name);
$query->setParameter('value', mb_strcut($property->getValue(), 0, 254));
$query->setParameter('preferred', $preferred);
$query->execute();
}
$query->setParameter('name', $property->name);
$query->setParameter('value', mb_strcut($property->getValue(), 0, 254));
$query->setParameter('preferred', $preferred);
$query->execute();
$this->db->commit();
} catch (\Exception $e) {
$this->db->rollBack();
}
}

Expand Down
4 changes: 2 additions & 2 deletions apps/dav/lib/CardDAV/SyncService.php
Original file line number Diff line number Diff line change
Expand Up @@ -265,12 +265,12 @@ public function updateUser(IUser $user) {
$userId = $user->getUID();

$cardId = "$name:$userId.vcf";
$card = $this->backend->getCard($addressBookId, $cardId);
if ($user->isEnabled()) {
$card = $this->backend->getCard($addressBookId, $cardId);
if ($card === false) {
$vCard = $this->converter->createCardFromUser($user);
if ($vCard !== null) {
$this->backend->createCard($addressBookId, $cardId, $vCard->serialize());
$this->backend->createCard($addressBookId, $cardId, $vCard->serialize(), false);
}
} else {
$vCard = $this->converter->createCardFromUser($user);
Expand Down
12 changes: 7 additions & 5 deletions apps/dav/lib/HookManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,7 @@ public function setup() {
$this->postDeleteUser(['uid' => $uid]);
});
\OC::$server->getUserManager()->listen('\OC\User', 'postUnassignedUserId', [$this, 'postUnassignedUserId']);
Util::connectHook('OC_User',
'changeUser',
$this,
'changeUser');
Util::connectHook('OC_User', 'changeUser', $this, 'changeUser');
}

public function postCreateUser($params) {
Expand Down Expand Up @@ -164,7 +161,12 @@ public function postUnassignedUserId($uid) {

public function changeUser($params) {
$user = $params['user'];
$this->syncService->updateUser($user);
$feature = $params['feature'];
// This case is already covered by the account manager firing up a signal
// later on
if ($feature !== 'eMailAddress' && $feature !== 'displayName') {
$this->syncService->updateUser($user);
}
}

public function firstLogin(IUser $user = null) {
Expand Down
18 changes: 9 additions & 9 deletions lib/private/Accounts/AccountManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -269,12 +269,15 @@ protected function sanitizeWebsite(IAccountProperty $property, bool $throwOnData
}
}

protected function updateUser(IUser $user, array $data, bool $throwOnData = false): array {
$oldUserData = $this->getUser($user, false);
protected function updateUser(IUser $user, array $data, ?array $oldUserData, bool $throwOnData = false): array {
if ($oldUserData === null) {
$oldUserData = $this->getUser($user, false);
}

$updated = true;

if ($oldUserData !== $data) {
$this->updateExistingUser($user, $data);
$this->updateExistingUser($user, $data, $oldUserData);
} else {
// nothing needs to be done if new and old data set are the same
$updated = false;
Expand Down Expand Up @@ -601,12 +604,9 @@ protected function importFromJson(string $json, string $userId): ?array {
}

/**
* update existing user in accounts table
*
* @param IUser $user
* @param array $data
* Update existing user in accounts table
*/
protected function updateExistingUser(IUser $user, array $data): void {
protected function updateExistingUser(IUser $user, array $data, array $oldData): void {
$uid = $user->getUID();
$jsonEncodedData = $this->prepareJson($data);
$query = $this->connection->getQueryBuilder();
Expand Down Expand Up @@ -820,7 +820,7 @@ public function updateAccount(IAccount $account): void {
];
}

$this->updateUser($account->getUser(), $data, true);
$this->updateUser($account->getUser(), $data, $oldData, true);
$this->internalCache->set($account->getUser()->getUID(), $account);
}
}
9 changes: 3 additions & 6 deletions tests/lib/Accounts/AccountManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ protected function populateOrUpdate(): void {
],
];
foreach ($users as $userInfo) {
$this->invokePrivate($this->accountManager, 'updateUser', [$userInfo['user'], $userInfo['data'], false]);
$this->invokePrivate($this->accountManager, 'updateUser', [$userInfo['user'], $userInfo['data'], null, false]);
}
}

Expand Down Expand Up @@ -466,9 +466,6 @@ public function testUpdateUser($newData, $oldData, $insertNew, $updateExisting)
/** @var IUser $user */
$user = $this->createMock(IUser::class);

// FIXME: should be an integration test instead of this abomination
$accountManager->expects($this->once())->method('getUser')->with($user)->willReturn($oldData);

if ($updateExisting) {
$accountManager->expects($this->once())->method('updateExistingUser')
->with($user, $newData);
Expand Down Expand Up @@ -497,10 +494,10 @@ function ($eventName, $event) use ($user, $newData) {
);
}

$this->invokePrivate($accountManager, 'updateUser', [$user, $newData]);
$this->invokePrivate($accountManager, 'updateUser', [$user, $newData, $oldData]);
}

public function dataTrueFalse() {
public function dataTrueFalse(): array {
return [
#$newData | $oldData | $insertNew | $updateExisting
[['myProperty' => ['value' => 'newData']], ['myProperty' => ['value' => 'oldData']], false, true],
Expand Down

0 comments on commit 9fcf531

Please sign in to comment.