]> source.dussan.org Git - nextcloud-server.git/commitdiff
cache calendar objects from calendarQuery 39858/head
authorRobin Appelman <robin@icewind.nl>
Tue, 25 Jul 2023 16:09:11 +0000 (18:09 +0200)
committerbackportbot-nextcloud[bot] <backportbot-nextcloud[bot]@users.noreply.github.com>
Mon, 14 Aug 2023 09:10:19 +0000 (09:10 +0000)
Signed-off-by: Robin Appelman <robin@icewind.nl>
apps/dav/lib/CalDAV/CalDavBackend.php

index b8319779c5b32988db3fc4ebbd38db2a08929234..4c1acfbfbfe3d8ec7a82d5c54863e2d0eaf967d9 100644 (file)
@@ -217,6 +217,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
        private IConfig $config;
        private bool $legacyEndpoint;
        private string $dbObjectPropertiesTable = 'calendarobjects_props';
+       private array $cachedObjects = [];
 
        public function __construct(IDBConnection $db,
                                                                Principal $principalBackend,
@@ -1112,6 +1113,10 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
         * @return array|null
         */
        public function getCalendarObject($calendarId, $objectUri, int $calendarType = self::CALENDAR_TYPE_CALENDAR) {
+               $key = $calendarId . '::' . $objectUri . '::' . $calendarType;
+               if (isset($this->cachedObjects[$key])) {
+                       return $this->cachedObjects[$key];
+               }
                $query = $this->db->getQueryBuilder();
                $query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype', 'classification', 'deleted_at'])
                        ->from('calendarobjects')
@@ -1126,6 +1131,12 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                        return null;
                }
 
+               $object = $this->rowToCalendarObject($row);
+               $this->cachedObjects[$key] = $object;
+               return $object;
+       }
+
+       private function rowToCalendarObject(array $row): array {
                return [
                        'id' => $row['id'],
                        'uri' => $row['uri'],
@@ -1212,6 +1223,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
         * @return string
         */
        public function createCalendarObject($calendarId, $objectUri, $calendarData, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
+               $this->cachedObjects = [];
                $extraData = $this->getDenormalizedData($calendarData);
 
                return $this->atomic(function () use ($calendarId, $objectUri, $calendarData, $extraData, $calendarType) {
@@ -1306,6 +1318,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
         * @return string
         */
        public function updateCalendarObject($calendarId, $objectUri, $calendarData, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
+               $this->cachedObjects = [];
                $extraData = $this->getDenormalizedData($calendarData);
 
                return $this->atomic(function () use ($calendarId, $objectUri, $calendarData, $extraData, $calendarType) {
@@ -1359,6 +1372,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
         * @throws Exception
         */
        public function moveCalendarObject(int $sourceCalendarId, int $targetCalendarId, int $objectId, string $oldPrincipalUri, string $newPrincipalUri, int $calendarType = self::CALENDAR_TYPE_CALENDAR): bool {
+               $this->cachedObjects = [];
                return $this->atomic(function () use ($sourceCalendarId, $targetCalendarId, $objectId, $oldPrincipalUri, $newPrincipalUri, $calendarType) {
                        $object = $this->getCalendarObjectById($oldPrincipalUri, $objectId);
                        if (empty($object)) {
@@ -1406,6 +1420,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
         * @param int $classification
         */
        public function setClassification($calendarObjectId, $classification) {
+               $this->cachedObjects = [];
                if (!in_array($classification, [
                        self::CLASSIFICATION_PUBLIC, self::CLASSIFICATION_PRIVATE, self::CLASSIFICATION_CONFIDENTIAL
                ])) {
@@ -1430,6 +1445,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
         * @return void
         */
        public function deleteCalendarObject($calendarId, $objectUri, $calendarType = self::CALENDAR_TYPE_CALENDAR, bool $forceDeletePermanently = false) {
+               $this->cachedObjects = [];
                $this->atomic(function () use ($calendarId, $objectUri, $calendarType, $forceDeletePermanently) {
                        $data = $this->getCalendarObject($calendarId, $objectUri, $calendarType);
 
@@ -1511,6 +1527,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
         * @throws Forbidden
         */
        public function restoreCalendarObject(array $objectData): void {
+               $this->cachedObjects = [];
                $this->atomic(function () use ($objectData) {
                        $id = (int) $objectData['id'];
                        $restoreUri = str_replace("-deleted.ics", ".ics", $objectData['uri']);
@@ -1638,12 +1655,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                                }
                        }
                }
-               $columns = ['uri'];
-               if ($requirePostFilter) {
-                       $columns = ['uri', 'calendardata'];
-               }
                $query = $this->db->getQueryBuilder();
-               $query->select($columns)
+               $query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype', 'classification', 'deleted_at'])
                        ->from('calendarobjects')
                        ->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
                        ->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)))
@@ -1664,6 +1677,11 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
 
                $result = [];
                while ($row = $stmt->fetch()) {
+                       // if we leave it as a blob we can't read it both from the post filter and the rowToCalendarObject
+                       if (isset($row['calendardata'])) {
+                               $row['calendardata'] = $this->readBlob($row['calendardata']);
+                       }
+
                        if ($requirePostFilter) {
                                // validateFilterForObject will parse the calendar data
                                // catch parsing errors
@@ -1688,6 +1706,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                                }
                        }
                        $result[] = $row['uri'];
+                       $key = $calendarId . '::' . $row['uri'] . '::' . $calendarType;
+                       $this->cachedObjects[$key] = $this->rowToCalendarObject($row);
                }
 
                return $result;
@@ -2648,6 +2668,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
         * @return void
         */
        public function deleteSchedulingObject($principalUri, $objectUri) {
+               $this->cachedObjects = [];
                $query = $this->db->getQueryBuilder();
                $query->delete('schedulingobjects')
                                ->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri)))
@@ -2664,6 +2685,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
         * @return void
         */
        public function createSchedulingObject($principalUri, $objectUri, $objectData) {
+               $this->cachedObjects = [];
                $query = $this->db->getQueryBuilder();
                $query->insert('schedulingobjects')
                        ->values([
@@ -2687,6 +2709,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
         * @return void
         */
        protected function addChange(int $calendarId, string $objectUri, int $operation, int $calendarType = self::CALENDAR_TYPE_CALENDAR): void {
+               $this->cachedObjects = [];
                $table = $calendarType === self::CALENDAR_TYPE_CALENDAR ? 'calendars': 'calendarsubscriptions';
 
                $this->atomic(function () use ($calendarId, $objectUri, $operation, $calendarType, $table) {
@@ -2933,6 +2956,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
         * @param int $calendarType
         */
        public function updateProperties($calendarId, $objectUri, $calendarData, $calendarType = self::CALENDAR_TYPE_CALENDAR) {
+               $this->cachedObjects = [];
                $this->atomic(function () use ($calendarId, $objectUri, $calendarData, $calendarType) {
                        $objectId = $this->getCalendarObjectId($calendarId, $objectUri, $calendarType);
 
@@ -3097,6 +3121,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
         * @param int $objectId
         */
        protected function purgeProperties($calendarId, $objectId) {
+               $this->cachedObjects = [];
                $query = $this->db->getQueryBuilder();
                $query->delete($this->dbObjectPropertiesTable)
                        ->where($query->expr()->eq('objectid', $query->createNamedParameter($objectId)))