summaryrefslogtreecommitdiffstats
path: root/apps/files
diff options
context:
space:
mode:
authorThomas Müller <thomas.mueller@tmit.eu>2015-04-10 00:09:56 +0200
committerThomas Müller <thomas.mueller@tmit.eu>2015-04-10 00:09:56 +0200
commit02614d214e3ddc2234d570635adfb7eaa4d70ba1 (patch)
tree9d76008738e67b9d4623cf4c714c0f8ad4aae4ec /apps/files
parent13178db46503402cf9fe34235519e3335c788752 (diff)
parentcefdcea02171672d6340d9db57a54ffac78c5ab8 (diff)
downloadnextcloud-server-02614d214e3ddc2234d570635adfb7eaa4d70ba1.tar.gz
nextcloud-server-02614d214e3ddc2234d570635adfb7eaa4d70ba1.zip
Merge pull request #15437 from owncloud/deleteorphanedfiles
[command] delete orphaned file cache entries
Diffstat (limited to 'apps/files')
-rw-r--r--apps/files/appinfo/register_command.php1
-rw-r--r--apps/files/command/deleteorphanedfiles.php63
-rw-r--r--apps/files/tests/command/deleteorphanedfilestest.php116
3 files changed, 180 insertions, 0 deletions
diff --git a/apps/files/appinfo/register_command.php b/apps/files/appinfo/register_command.php
index 7a2f39c3da7..3042c259872 100644
--- a/apps/files/appinfo/register_command.php
+++ b/apps/files/appinfo/register_command.php
@@ -21,3 +21,4 @@
*/
$application->add(new OCA\Files\Command\Scan(OC_User::getManager()));
+$application->add(new OCA\Files\Command\DeleteOrphanedFiles(\OC::$server->getDatabaseConnection()));
diff --git a/apps/files/command/deleteorphanedfiles.php b/apps/files/command/deleteorphanedfiles.php
new file mode 100644
index 00000000000..0dc9c29f4f7
--- /dev/null
+++ b/apps/files/command/deleteorphanedfiles.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * @author Morris Jobke <hey@morrisjobke.de>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\Files\Command;
+
+use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
+use Doctrine\DBAL\Platforms\SqlitePlatform;
+use OCP\IDBConnection;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Delete all file entries that have no matching entries in the storage table.
+ */
+class DeleteOrphanedFiles extends Command {
+
+ /**
+ * @var IDBConnection
+ */
+ protected $connection;
+
+ public function __construct(IDBConnection $connection) {
+ $this->connection = $connection;
+ parent::__construct();
+ }
+
+ protected function configure() {
+ $this
+ ->setName('files:cleanup')
+ ->setDescription('cleanup filecache');
+ }
+
+ public function execute(InputInterface $input, OutputInterface $output) {
+
+ $sql =
+ 'DELETE FROM `*PREFIX*filecache` ' .
+ 'WHERE NOT EXISTS ' .
+ '(SELECT 1 FROM `*PREFIX*storages` WHERE `storage` = `numeric_id`)';
+
+ $deletedEntries = $this->connection->executeUpdate($sql);
+ $output->writeln("$deletedEntries orphaned file cache entries deleted");
+ }
+
+}
diff --git a/apps/files/tests/command/deleteorphanedfilestest.php b/apps/files/tests/command/deleteorphanedfilestest.php
new file mode 100644
index 00000000000..76fe9dbdfa0
--- /dev/null
+++ b/apps/files/tests/command/deleteorphanedfilestest.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ * @author Morris Jobke <hey@morrisjobke.de>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\Files\Tests\Command;
+
+use OCA\Files\Command\DeleteOrphanedFiles;
+
+class DeleteOrphanedFilesTest extends \Test\TestCase {
+
+ /**
+ * @var DeleteOrphanedFiles
+ */
+ private $command;
+
+ /**
+ * @var \OCP\IDBConnection
+ */
+ private $connection;
+
+ /**
+ * @var string
+ */
+ private $user1;
+
+ protected function setup() {
+ parent::setUp();
+
+ $this->connection = \OC::$server->getDatabaseConnection();
+
+ $this->user1 = $this->getUniqueID('user1_');
+
+ $userManager = \OC::$server->getUserManager();
+ $userManager->createUser($this->user1, 'pass');
+
+ $this->command = new DeleteOrphanedFiles($this->connection);
+ }
+
+ protected function tearDown() {
+ $userManager = \OC::$server->getUserManager();
+ $user1 = $userManager->get($this->user1);
+ if($user1) {
+ $user1->delete();
+ }
+
+ $this->logout();
+
+ parent::tearDown();
+ }
+
+ protected function getFile($fileId) {
+ $stmt = $this->connection->executeQuery('SELECT * FROM `*PREFIX*filecache` WHERE `fileid` = ?', [$fileId]);
+ return $stmt->fetchAll();
+ }
+
+ /**
+ * Test clearing orphaned files
+ */
+ public function testClearFiles() {
+ $input = $this->getMockBuilder('Symfony\Component\Console\Input\InputInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $output = $this->getMockBuilder('Symfony\Component\Console\Output\OutputInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->loginAsUser($this->user1);
+
+ $view = new \OC\Files\View('/' . $this->user1 . '/');
+ $view->mkdir('files/test');
+
+ $fileInfo = $view->getFileInfo('files/test');
+
+ $storageId = $fileInfo->getStorage()->getId();
+
+ $this->assertCount(1, $this->getFile($fileInfo->getId()), 'Asserts that file is available');
+
+ $this->command->execute($input, $output);
+
+ $this->assertCount(1, $this->getFile($fileInfo->getId()), 'Asserts that file is still available');
+
+ $deletedRows = $this->connection->executeUpdate('DELETE FROM `*PREFIX*storages` WHERE `id` = ?', [$storageId]);
+ $this->assertNotNull($deletedRows, 'Asserts that storage got deleted');
+ $this->assertSame(1, $deletedRows, 'Asserts that storage got deleted');
+
+ // parent folder, `files`, ´test` and `welcome.txt` => 4 elements
+ $output
+ ->expects($this->once())
+ ->method('writeln')
+ ->with('4 orphaned file cache entries deleted');
+
+ $this->command->execute($input, $output);
+
+ $this->assertCount(0, $this->getFile($fileInfo->getId()), 'Asserts that file gets cleaned up');
+
+ $view->unlink('files/test');
+ }
+}
+