9999use Sabre \VObject \Reader ;
100100use Sabre \VObject \Recur \EventIterator ;
101101use function array_column ;
102+ use function array_map ;
102103use function array_merge ;
103104use function array_values ;
104105use function explode ;
@@ -868,7 +869,7 @@ public function updateCalendar($calendarId, PropPatch $propPatch) {
868869 $ query ->where ($ query ->expr ()->eq ('id ' , $ query ->createNamedParameter ($ calendarId )));
869870 $ query ->executeStatement ();
870871
871- $ this ->addChange ($ calendarId , "" , 2 );
872+ $ this ->addChanges ($ calendarId , [ "" ] , 2 );
872873
873874 $ calendarData = $ this ->getCalendarById ($ calendarId );
874875 $ shares = $ this ->getShares ($ calendarId );
@@ -1287,7 +1288,7 @@ public function createCalendarObject($calendarId, $objectUri, $calendarData, $ca
12871288 ->executeStatement ();
12881289
12891290 $ this ->updateProperties ($ calendarId , $ objectUri , $ calendarData , $ calendarType );
1290- $ this ->addChange ($ calendarId , $ objectUri , 1 , $ calendarType );
1291+ $ this ->addChanges ($ calendarId , [ $ objectUri] , 1 , $ calendarType );
12911292
12921293 $ objectRow = $ this ->getCalendarObject ($ calendarId , $ objectUri , $ calendarType );
12931294 assert ($ objectRow !== null );
@@ -1348,7 +1349,7 @@ public function updateCalendarObject($calendarId, $objectUri, $calendarData, $ca
13481349 ->executeStatement ();
13491350
13501351 $ this ->updateProperties ($ calendarId , $ objectUri , $ calendarData , $ calendarType );
1351- $ this ->addChange ($ calendarId , $ objectUri , 2 , $ calendarType );
1352+ $ this ->addChanges ($ calendarId , [ $ objectUri] , 2 , $ calendarType );
13521353
13531354 $ objectRow = $ this ->getCalendarObject ($ calendarId , $ objectUri , $ calendarType );
13541355 if (is_array ($ objectRow )) {
@@ -1398,8 +1399,8 @@ public function moveCalendarObject(int $sourceCalendarId, int $targetCalendarId,
13981399 $ this ->purgeProperties ($ sourceCalendarId , $ objectId );
13991400 $ this ->updateProperties ($ targetCalendarId , $ object ['uri ' ], $ object ['calendardata ' ], $ calendarType );
14001401
1401- $ this ->addChange ($ sourceCalendarId , $ object ['uri ' ], 3 , $ calendarType );
1402- $ this ->addChange ($ targetCalendarId , $ object ['uri ' ], 1 , $ calendarType );
1402+ $ this ->addChanges ($ sourceCalendarId , [ $ object ['uri ' ] ], 3 , $ calendarType );
1403+ $ this ->addChanges ($ targetCalendarId , [ $ object ['uri ' ] ], 1 , $ calendarType );
14031404
14041405 $ object = $ this ->getCalendarObjectById ($ newPrincipalUri , $ objectId );
14051406 // Calendar Object wasn't found - possibly because it was deleted in the meantime by a different client
@@ -1526,7 +1527,7 @@ public function deleteCalendarObject($calendarId, $objectUri, $calendarType = se
15261527 }
15271528 }
15281529
1529- $ this ->addChange ($ calendarId , $ objectUri , 3 , $ calendarType );
1530+ $ this ->addChanges ($ calendarId , [ $ objectUri] , 3 , $ calendarType );
15301531 }, $ this ->db );
15311532 }
15321533
@@ -1568,7 +1569,7 @@ public function restoreCalendarObject(array $objectData): void {
15681569 // Welp, this should possibly not have happened, but let's ignore
15691570 return ;
15701571 }
1571- $ this ->addChange ($ row ['calendarid ' ], $ row ['uri ' ], 1 , (int ) $ row ['calendartype ' ]);
1572+ $ this ->addChanges ($ row ['calendarid ' ], [ $ row ['uri ' ] ], 1 , (int ) $ row ['calendartype ' ]);
15721573
15731574 $ calendarRow = $ this ->getCalendarById ((int ) $ row ['calendarid ' ]);
15741575 if ($ calendarRow === null ) {
@@ -2749,16 +2750,16 @@ public function createSchedulingObject($principalUri, $objectUri, $objectData) {
27492750 * Adds a change record to the calendarchanges table.
27502751 *
27512752 * @param mixed $calendarId
2752- * @param string $objectUri
2753+ * @param string[] $objectUris
27532754 * @param int $operation 1 = add, 2 = modify, 3 = delete.
27542755 * @param int $calendarType
27552756 * @return void
27562757 */
2757- protected function addChange (int $ calendarId , string $ objectUri , int $ operation , int $ calendarType = self ::CALENDAR_TYPE_CALENDAR ): void {
2758+ protected function addChanges (int $ calendarId , array $ objectUris , int $ operation , int $ calendarType = self ::CALENDAR_TYPE_CALENDAR ): void {
27582759 $ this ->cachedObjects = [];
27592760 $ table = $ calendarType === self ::CALENDAR_TYPE_CALENDAR ? 'calendars ' : 'calendarsubscriptions ' ;
27602761
2761- $ this ->atomic (function () use ($ calendarId , $ objectUri , $ operation , $ calendarType , $ table ) {
2762+ $ this ->atomic (function () use ($ calendarId , $ objectUris , $ operation , $ calendarType , $ table ) {
27622763 $ query = $ this ->db ->getQueryBuilder ();
27632764 $ query ->select ('synctoken ' )
27642765 ->from ($ table )
@@ -2770,13 +2771,16 @@ protected function addChange(int $calendarId, string $objectUri, int $operation,
27702771 $ query = $ this ->db ->getQueryBuilder ();
27712772 $ query ->insert ('calendarchanges ' )
27722773 ->values ([
2773- 'uri ' => $ query ->createNamedParameter ( $ objectUri ),
2774+ 'uri ' => $ query ->createParameter ( ' uri ' ),
27742775 'synctoken ' => $ query ->createNamedParameter ($ syncToken ),
27752776 'calendarid ' => $ query ->createNamedParameter ($ calendarId ),
27762777 'operation ' => $ query ->createNamedParameter ($ operation ),
27772778 'calendartype ' => $ query ->createNamedParameter ($ calendarType ),
2778- ])
2779- ->executeStatement ();
2779+ ]);
2780+ foreach ($ objectUris as $ uri ) {
2781+ $ query ->setParameter ('uri ' , $ uri );
2782+ $ query ->executeStatement ();
2783+ }
27802784
27812785 $ query = $ this ->db ->getQueryBuilder ();
27822786 $ query ->update ($ table )
@@ -2786,6 +2790,47 @@ protected function addChange(int $calendarId, string $objectUri, int $operation,
27862790 }, $ this ->db );
27872791 }
27882792
2793+ public function restoreChanges (int $ calendarId , int $ calendarType = self ::CALENDAR_TYPE_CALENDAR ): void {
2794+ $ this ->cachedObjects = [];
2795+
2796+ $ this ->atomic (function () use ($ calendarId , $ calendarType ) {
2797+ $ qbAdded = $ this ->db ->getQueryBuilder ();
2798+ $ qbAdded ->select ('uri ' )
2799+ ->from ('calendarobjects ' )
2800+ ->where (
2801+ $ qbAdded ->expr ()->andX (
2802+ $ qbAdded ->expr ()->eq ('calendarid ' , $ qbAdded ->createNamedParameter ($ calendarId )),
2803+ $ qbAdded ->expr ()->eq ('calendartype ' , $ qbAdded ->createNamedParameter ($ calendarType )),
2804+ $ qbAdded ->expr ()->isNull ('deleted_at ' ),
2805+ )
2806+ );
2807+ $ resultAdded = $ qbAdded ->executeQuery ();
2808+ $ addedUris = $ resultAdded ->fetchAll (\PDO ::FETCH_COLUMN );
2809+ $ resultAdded ->closeCursor ();
2810+ // Track everything as changed
2811+ // Tracking the creation is not necessary because \OCA\DAV\CalDAV\CalDavBackend::getChangesForCalendar
2812+ // only returns the last change per object.
2813+ $ this ->addChanges ($ calendarId , $ addedUris , 2 , $ calendarType );
2814+
2815+ $ qbDeleted = $ this ->db ->getQueryBuilder ();
2816+ $ qbDeleted ->select ('uri ' )
2817+ ->from ('calendarobjects ' )
2818+ ->where (
2819+ $ qbDeleted ->expr ()->andX (
2820+ $ qbDeleted ->expr ()->eq ('calendarid ' , $ qbDeleted ->createNamedParameter ($ calendarId )),
2821+ $ qbDeleted ->expr ()->eq ('calendartype ' , $ qbDeleted ->createNamedParameter ($ calendarType )),
2822+ $ qbDeleted ->expr ()->isNotNull ('deleted_at ' ),
2823+ )
2824+ );
2825+ $ resultDeleted = $ qbDeleted ->executeQuery ();
2826+ $ deletedUris = array_map (function (string $ uri ) {
2827+ return str_replace ("-deleted.ics " , ".ics " , $ uri );
2828+ }, $ resultDeleted ->fetchAll (\PDO ::FETCH_COLUMN ));
2829+ $ resultDeleted ->closeCursor ();
2830+ $ this ->addChanges ($ calendarId , $ deletedUris , 3 , $ calendarType );
2831+ }, $ this ->db );
2832+ }
2833+
27892834 /**
27902835 * Parses some information from calendar objects, used for optimized
27912836 * calendar-queries.
@@ -3127,9 +3172,7 @@ public function purgeAllCachedEventsForSubscription($subscriptionId) {
31273172 ->andWhere ($ query ->expr ()->eq ('calendartype ' , $ query ->createNamedParameter (self ::CALENDAR_TYPE_SUBSCRIPTION )))
31283173 ->executeStatement ();
31293174
3130- foreach ($ uris as $ uri ) {
3131- $ this ->addChange ($ subscriptionId , $ uri , 3 , self ::CALENDAR_TYPE_SUBSCRIPTION );
3132- }
3175+ $ this ->addChanges ($ subscriptionId , $ uris , 3 , self ::CALENDAR_TYPE_SUBSCRIPTION );
31333176 }, $ this ->db );
31343177 }
31353178
0 commit comments