]> source.dussan.org Git - nextcloud-server.git/commitdiff
Remove orphan event and contacts data 15387/head
authorJoas Schilling <coding@schilljs.com>
Fri, 11 Jan 2019 11:36:31 +0000 (12:36 +0100)
committerJoas Schilling <coding@schilljs.com>
Mon, 6 May 2019 10:49:54 +0000 (12:49 +0200)
Signed-off-by: Joas Schilling <coding@schilljs.com>
apps/dav/appinfo/info.xml
apps/dav/composer/composer/autoload_classmap.php
apps/dav/composer/composer/autoload_static.php
apps/dav/lib/Migration/RemoveOrphanEventsAndContacts.php [new file with mode: 0644]

index 02e5573a46145fbb0ea5bc91f44d5858c60b0543..8bb662eeb54f2b7b6ba3f5baa7ba7b5bed2f90fc 100644 (file)
@@ -5,7 +5,7 @@
        <name>WebDAV</name>
        <summary>WebDAV endpoint</summary>
        <description>WebDAV endpoint</description>
-       <version>1.8.1</version>
+       <version>1.8.2</version>
        <licence>agpl</licence>
        <author>owncloud.org</author>
        <namespace>DAV</namespace>
@@ -31,6 +31,7 @@
                        <step>OCA\DAV\Migration\CalDAVRemoveEmptyValue</step>
                        <step>OCA\DAV\Migration\BuildCalendarSearchIndex</step>
                        <step>OCA\DAV\Migration\RefreshWebcalJobRegistrar</step>
+                       <step>OCA\DAV\Migration\RemoveOrphanEventsAndContacts</step>
                        <step>OCA\DAV\Migration\RemoveClassifiedEventActivity</step>
                </post-migration>
        </repair-steps>
index 539ba5d05332732c967ecd672f652e036b940da7..9581403e5cc1be9a3392e515cec7b3c0cb14f8fa 100644 (file)
@@ -156,6 +156,7 @@ return array(
     'OCA\\DAV\\Migration\\FixBirthdayCalendarComponent' => $baseDir . '/../lib/Migration/FixBirthdayCalendarComponent.php',
     'OCA\\DAV\\Migration\\RefreshWebcalJobRegistrar' => $baseDir . '/../lib/Migration/RefreshWebcalJobRegistrar.php',
     'OCA\\DAV\\Migration\\RemoveClassifiedEventActivity' => $baseDir . '/../lib/Migration/RemoveClassifiedEventActivity.php',
+    'OCA\\DAV\\Migration\\RemoveOrphanEventsAndContacts' => $baseDir . '/../lib/Migration/RemoveOrphanEventsAndContacts.php',
     'OCA\\DAV\\Migration\\Version1004Date20170825134824' => $baseDir . '/../lib/Migration/Version1004Date20170825134824.php',
     'OCA\\DAV\\Migration\\Version1004Date20170919104507' => $baseDir . '/../lib/Migration/Version1004Date20170919104507.php',
     'OCA\\DAV\\Migration\\Version1004Date20170924124212' => $baseDir . '/../lib/Migration/Version1004Date20170924124212.php',
index 5a23166b027a5b133b765acf45bba02040fbdf55..4dde96b6c035ef0a80b4b211dd841eaaafc0f905 100644 (file)
@@ -171,6 +171,7 @@ class ComposerStaticInitDAV
         'OCA\\DAV\\Migration\\FixBirthdayCalendarComponent' => __DIR__ . '/..' . '/../lib/Migration/FixBirthdayCalendarComponent.php',
         'OCA\\DAV\\Migration\\RefreshWebcalJobRegistrar' => __DIR__ . '/..' . '/../lib/Migration/RefreshWebcalJobRegistrar.php',
         'OCA\\DAV\\Migration\\RemoveClassifiedEventActivity' => __DIR__ . '/..' . '/../lib/Migration/RemoveClassifiedEventActivity.php',
+        'OCA\\DAV\\Migration\\RemoveOrphanEventsAndContacts' => __DIR__ . '/..' . '/../lib/Migration/RemoveOrphanEventsAndContacts.php',
         'OCA\\DAV\\Migration\\Version1004Date20170825134824' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170825134824.php',
         'OCA\\DAV\\Migration\\Version1004Date20170919104507' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170919104507.php',
         'OCA\\DAV\\Migration\\Version1004Date20170924124212' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170924124212.php',
diff --git a/apps/dav/lib/Migration/RemoveOrphanEventsAndContacts.php b/apps/dav/lib/Migration/RemoveOrphanEventsAndContacts.php
new file mode 100644 (file)
index 0000000..1764358
--- /dev/null
@@ -0,0 +1,94 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2019 Joas Schilling <coding@schilljs.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\DAV\Migration;
+
+use OCA\DAV\CalDAV\CalDavBackend;
+use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\IDBConnection;
+use OCP\Migration\IOutput;
+use OCP\Migration\IRepairStep;
+
+class RemoveOrphanEventsAndContacts implements IRepairStep {
+
+       /** @var IDBConnection */
+       private $connection;
+
+       public function __construct(IDBConnection $connection) {
+               $this->connection = $connection;
+       }
+
+       /**
+        * @inheritdoc
+        */
+       public function getName(): string {
+               return 'Clean up orphan event and contact data';
+       }
+
+       /**
+        * @inheritdoc
+        */
+       public function run(IOutput $output) {
+               $orphanItems = $this->removeOrphanChildren('calendarobjects', 'calendars',  'calendarid');
+               $output->info(sprintf('%d events without a calendar have been cleaned up', $orphanItems));
+               $orphanItems = $this->removeOrphanChildren('calendarobjects_props', 'calendarobjects',  'objectid');
+               $output->info(sprintf('%d properties without an events have been cleaned up', $orphanItems));
+               $orphanItems = $this->removeOrphanChildren('calendarchanges', 'calendars',  'calendarid');
+               $output->info(sprintf('%d changes without a calendar have been cleaned up', $orphanItems));
+
+               $orphanItems = $this->removeOrphanChildren('cards', 'addressbooks',  'addressbookid');
+               $output->info(sprintf('%d contacts without an addressbook have been cleaned up', $orphanItems));
+               $orphanItems = $this->removeOrphanChildren('cards_properties', 'cards',  'cardid');
+               $output->info(sprintf('%d properties without a contact have been cleaned up', $orphanItems));
+               $orphanItems = $this->removeOrphanChildren('addressbookchanges', 'addressbooks',  'addressbookid');
+               $output->info(sprintf('%d changes without an addressbook have been cleaned up', $orphanItems));
+       }
+
+       protected function removeOrphanChildren($childTable, $parentTable, $parentId): int {
+               $qb = $this->connection->getQueryBuilder();
+
+               $qb->select('c.id')
+                       ->from($childTable, 'c')
+                       ->leftJoin('c', $parentTable, 'p', $qb->expr()->eq('c.' . $parentId, 'p.id'))
+                       ->where($qb->expr()->isNull('p.id'));
+               $result = $qb->execute();
+
+               $orphanItems = array();
+               while ($row = $result->fetch()) {
+                       $orphanItems[] = (int) $row['id'];
+               }
+               $result->closeCursor();
+
+               if (!empty($orphanItems)) {
+                       $qb->delete($childTable)
+                               ->where($qb->expr()->in('id', $qb->createParameter('ids')));
+
+                       $orphanItemsBatch = array_chunk($orphanItems, 200);
+                       foreach ($orphanItemsBatch as $items) {
+                               $qb->setParameter('ids', $items, IQueryBuilder::PARAM_INT_ARRAY);
+                               $qb->execute();
+                       }
+               }
+
+               return count($orphanItems);
+       }
+}