diff --git a/lib/Data.php b/lib/Data.php index e7704947f..95452656f 100755 --- a/lib/Data.php +++ b/lib/Data.php @@ -43,6 +43,12 @@ class Data { /** @var IDBConnection */ protected $connection; + /** @var ?IQueryBuilder */ + protected $insertActivity; + + /** @var ?IQueryBuilder */ + protected $insertMail; + /** * @param IManager $activityManager * @param IDBConnection $connection @@ -63,44 +69,47 @@ public function send(IEvent $event): int { return 0; } + if ($this->insertActivity === null) { + $this->insertActivity = $this->connection->getQueryBuilder(); + $this->insertActivity->insert('activity') + ->values([ + 'app' => $this->insertActivity->createParameter('app'), + 'subject' => $this->insertActivity->createParameter('subject'), + 'subjectparams' => $this->insertActivity->createParameter('subjectparams'), + 'message' => $this->insertActivity->createParameter('message'), + 'messageparams' => $this->insertActivity->createParameter('messageparams'), + 'file' => $this->insertActivity->createParameter('object_name'), + 'link' => $this->insertActivity->createParameter('link'), + 'user' => $this->insertActivity->createParameter('user'), + 'affecteduser' => $this->insertActivity->createParameter('affecteduser'), + 'timestamp' => $this->insertActivity->createParameter('timestamp'), + 'priority' => $this->insertActivity->createParameter('priority'), + 'type' => $this->insertActivity->createParameter('type'), + 'object_type' => $this->insertActivity->createParameter('object_type'), + 'object_id' => $this->insertActivity->createParameter('object_id'), + ]); + } + // store in DB - $queryBuilder = $this->connection->getQueryBuilder(); - $queryBuilder->insert('activity') - ->values([ - 'app' => $queryBuilder->createParameter('app'), - 'subject' => $queryBuilder->createParameter('subject'), - 'subjectparams' => $queryBuilder->createParameter('subjectparams'), - 'message' => $queryBuilder->createParameter('message'), - 'messageparams' => $queryBuilder->createParameter('messageparams'), - 'file' => $queryBuilder->createParameter('object_name'), - 'link' => $queryBuilder->createParameter('link'), - 'user' => $queryBuilder->createParameter('user'), - 'affecteduser' => $queryBuilder->createParameter('affecteduser'), - 'timestamp' => $queryBuilder->createParameter('timestamp'), - 'priority' => $queryBuilder->createParameter('priority'), - 'type' => $queryBuilder->createParameter('type'), - 'object_type' => $queryBuilder->createParameter('object_type'), - 'object_id' => $queryBuilder->createParameter('object_id'), - ]) - ->setParameters([ - 'app' => $event->getApp(), - 'type' => $event->getType(), - 'affecteduser' => $event->getAffectedUser(), - 'user' => $event->getAuthor(), - 'timestamp' => $event->getTimestamp(), - 'subject' => $event->getSubject(), - 'subjectparams' => json_encode($event->getSubjectParameters()), - 'message' => $event->getMessage(), - 'messageparams' => json_encode($event->getMessageParameters()), - 'priority' => IExtension::PRIORITY_MEDIUM, - 'object_type' => $event->getObjectType(), - 'object_id' => $event->getObjectId(), - 'object_name' => $event->getObjectName(), - 'link' => $event->getLink(), - ]) - ->execute(); - - return $queryBuilder->getLastInsertId(); + $this->insertActivity->setParameters([ + 'app' => $event->getApp(), + 'type' => $event->getType(), + 'affecteduser' => $event->getAffectedUser(), + 'user' => $event->getAuthor(), + 'timestamp' => $event->getTimestamp(), + 'subject' => $event->getSubject(), + 'subjectparams' => json_encode($event->getSubjectParameters()), + 'message' => $event->getMessage(), + 'messageparams' => json_encode($event->getMessageParameters()), + 'priority' => IExtension::PRIORITY_MEDIUM, + 'object_type' => $event->getObjectType(), + 'object_id' => $event->getObjectId(), + 'object_name' => $event->getObjectName(), + 'link' => $event->getLink(), + ]); + $this->insertActivity->executeStatement(); + + return $this->insertActivity->getLastInsertId(); } /** @@ -116,20 +125,35 @@ public function storeMail(IEvent $event, int $latestSendTime): bool { return false; } - $query = $this->connection->getQueryBuilder(); - $query->insert('activity_mq') - ->values([ - 'amq_appid' => $query->createNamedParameter($event->getApp()), - 'amq_subject' => $query->createNamedParameter($event->getSubject()), - 'amq_subjectparams' => $query->createNamedParameter(json_encode($event->getSubjectParameters())), - 'amq_affecteduser' => $query->createNamedParameter($affectedUser), - 'amq_timestamp' => $query->createNamedParameter($event->getTimestamp()), - 'amq_type' => $query->createNamedParameter($event->getType()), - 'amq_latest_send' => $query->createNamedParameter($latestSendTime), - 'object_type' => $query->createNamedParameter($event->getObjectType()), - 'object_id' => $query->createNamedParameter($event->getObjectId()), - ]); - $query->execute(); + if ($this->insertMail === null) { + $this->insertMail = $this->connection->getQueryBuilder(); + $this->insertMail->insert('activity_mq') + ->values([ + 'amq_appid' => $this->insertMail->createParameter('amq_appid'), + 'amq_subject' => $this->insertMail->createParameter('amq_subject'), + 'amq_subjectparams' => $this->insertMail->createParameter('amq_subjectparams'), + 'amq_affecteduser' => $this->insertMail->createParameter('amq_affecteduser'), + 'amq_timestamp' => $this->insertMail->createParameter('amq_timestamp'), + 'amq_type' => $this->insertMail->createParameter('amq_type'), + 'amq_latest_send' => $this->insertMail->createParameter('amq_latest_send'), + 'object_type' => $this->insertMail->createParameter('object_type'), + 'object_id' => $this->insertMail->createParameter('object_id'), + ]); + } + + $this->insertMail->setParameters([ + 'amq_appid' => $event->getApp(), + 'amq_subject' => $event->getSubject(), + 'amq_subjectparams' => json_encode($event->getSubjectParameters()), + 'amq_affecteduser' => $affectedUser, + 'amq_timestamp' => $event->getTimestamp(), + 'amq_type' => $event->getType(), + 'amq_latest_send' => $latestSendTime, + 'object_type' => $event->getObjectType(), + 'object_id' => $event->getObjectId(), + ]); + + $this->insertMail->executeStatement(); return true; } diff --git a/lib/FilesHooks.php b/lib/FilesHooks.php index db42a7660..9c1e23f8c 100755 --- a/lib/FilesHooks.php +++ b/lib/FilesHooks.php @@ -523,6 +523,7 @@ protected function generateDeleteActivities($users, $pathMap, $fileId, $oldFileN [$filteredEmailUsers, $filteredNotificationUsers] = $this->getFileChangeActivitySettings($fileId, $users); + $shouldFlush = $this->startActivityTransaction(); foreach ($users as $user) { $path = $pathMap[$user]; @@ -542,6 +543,7 @@ protected function generateDeleteActivities($users, $pathMap, $fileId, $oldFileN Files::TYPE_SHARE_DELETED ); } + $this->commitActivityTransaction($shouldFlush); } /** @@ -557,6 +559,7 @@ protected function generateAddActivities($users, $pathMap, $fileId, $fileName) { [$filteredEmailUsers, $filteredNotificationUsers] = $this->getFileChangeActivitySettings($fileId, $users); + $shouldFlush = $this->startActivityTransaction(); foreach ($users as $user) { $path = $pathMap[$user]; @@ -576,6 +579,7 @@ protected function generateAddActivities($users, $pathMap, $fileId, $fileName) { Files::TYPE_FILE_CHANGED ); } + $this->commitActivityTransaction($shouldFlush); } /** @@ -594,6 +598,7 @@ protected function generateMoveActivities($users, $beforePathMap, $afterPathMap, [$filteredEmailUsers, $filteredNotificationUsers] = $this->getFileChangeActivitySettings($fileId, $users); + $shouldFlush = $this->startActivityTransaction(); foreach ($users as $user) { if ($oldFileName === $fileName) { $userParams = [[$newParentId => $afterPathMap[$user] . '/']]; @@ -617,6 +622,7 @@ protected function generateMoveActivities($users, $beforePathMap, $afterPathMap, Files::TYPE_FILE_CHANGED ); } + $this->commitActivityTransaction($shouldFlush); } /** @@ -918,11 +924,13 @@ protected function unshareFromGroup(IShare $share) { $offset = 0; $users = $group->searchUsers('', self::USER_BATCH_SIZE, $offset); + $shouldFlush = $this->startActivityTransaction(); while (!empty($users)) { $this->addNotificationsForGroupUsers($users, $actionUser, $share->getNodeId(), $share->getNodeType(), $share->getTarget(), (int) $share->getId()); $offset += self::USER_BATCH_SIZE; $users = $group->searchUsers('', self::USER_BATCH_SIZE, $offset); } + $this->commitActivityTransaction($shouldFlush); } /** @@ -1004,6 +1012,7 @@ protected function addNotificationsForGroupUsers(array $usersInGroup, $actionUse $filteredNotificationUsers = $this->userSettings->filterUsersBySetting($userIds, 'notification', Files_Sharing::TYPE_SHARED); $affectedUsers = $this->fixPathsForShareExceptions($affectedUsers, $shareId); + $shouldFlush = $this->startActivityTransaction(); foreach ($affectedUsers as $user => $path) { $this->addNotificationsForUser( $user, $actionUser, [[$fileSource => $path], $this->currentUser->getUserIdentifier()], @@ -1012,6 +1021,7 @@ protected function addNotificationsForGroupUsers(array $usersInGroup, $actionUse $filteredNotificationUsers[$user] ?? false ); } + $this->commitActivityTransaction($shouldFlush); } /** @@ -1197,4 +1207,16 @@ protected function addNotificationsForUser($user, $subject, $subjectParams, $fil $this->activityData->storeMail($event, $latestSend); } } + + protected function startActivityTransaction(): bool { + $this->connection->beginTransaction(); + return $this->notificationGenerator->deferNotifications(); + } + + protected function commitActivityTransaction(bool $shouldFlush): void { + if ($shouldFlush) { + $this->notificationGenerator->flushNotifications(); + } + $this->connection->commit(); + } } diff --git a/lib/NotificationGenerator.php b/lib/NotificationGenerator.php index bf1c008fc..574ace63c 100644 --- a/lib/NotificationGenerator.php +++ b/lib/NotificationGenerator.php @@ -45,6 +45,14 @@ public function __construct(Data $data, ActivityManager $activityManager, Notifi $this->l10n = $l10n; } + public function deferNotifications(): bool { + return $this->notificationManager->defer(); + } + + public function flushNotifications() { + $this->notificationManager->flush(); + } + public function sendNotificationForEvent(IEvent $event, int $activityId) { $selfAction = $event->getAffectedUser() === $event->getAuthor(); $notifySetting = $this->userSettings->getUserSetting($event->getAffectedUser(), 'notification', $event->getType());