]> source.dussan.org Git - nextcloud-server.git/commitdiff
Also repair storage id's when repairing invalid entries 5786/head
authorRobin Appelman <robin@icewind.nl>
Wed, 19 Jul 2017 10:30:59 +0000 (12:30 +0200)
committerRobin Appelman <robin@icewind.nl>
Wed, 19 Jul 2017 10:34:00 +0000 (12:34 +0200)
Signed-off-by: Robin Appelman <robin@icewind.nl>
lib/private/Files/Cache/Cache.php
lib/private/Repair/NC13/RepairInvalidPaths.php
tests/lib/Repair/RepairInvalidPathsTest.php

index 1f3f2433e45cc6bc53211eb60dc9bd120dbc343a..9d8e67d1d1236c16819b421b09f1242baab0826d 100644 (file)
@@ -332,7 +332,7 @@ class Cache implements ICache {
        protected function buildParts(array $data) {
                $fields = array(
                        'path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'storage_mtime', 'encrypted',
-                       'etag', 'permissions', 'checksum');
+                       'etag', 'permissions', 'checksum', 'storage');
 
                $doNotCopyStorageMTime = false;
                if (array_key_exists('mtime', $data) && $data['mtime'] === null) {
index efc682bf44f4296666438a7b9b77976694f19fba..9d1463a5e1f6986ce5ee7a873c306e53c100b928 100644 (file)
@@ -60,7 +60,7 @@ class RepairInvalidPaths implements IRepairStep {
                );
 
                //select f.path, f.parent,p.path from oc_filecache f inner join oc_filecache p on f.parent=p.fileid and p.path!='' where f.path != p.path || '/' || f.name;
-               $query = $builder->select('f.fileid', 'f.path', 'p.path AS parent_path', 'f.name', 'f.parent', 'f.storage')
+               $query = $builder->select('f.fileid', 'f.path', 'p.path AS parent_path', 'f.name', 'f.parent', 'f.storage', 'p.storage as parent_storage')
                        ->from('filecache', 'f')
                        ->innerJoin('f', 'filecache', 'p', $builder->expr()->andX(
                                $builder->expr()->eq('f.parent', 'p.fileid'),
@@ -95,17 +95,19 @@ class RepairInvalidPaths implements IRepairStep {
                return $this->getIdQuery->execute()->fetchColumn();
        }
 
-       private function update($fileid, $newPath) {
+       private function update($fileid, $newPath, $newStorage) {
                if (!$this->updateQuery) {
                        $builder = $this->connection->getQueryBuilder();
 
                        $this->updateQuery = $builder->update('filecache')
                                ->set('path', $builder->createParameter('newpath'))
                                ->set('path_hash', $builder->func()->md5($builder->createParameter('newpath')))
+                               ->set('storage', $builder->createParameter('newstorage'))
                                ->where($builder->expr()->eq('fileid', $builder->createParameter('fileid')));
                }
 
                $this->updateQuery->setParameter('newpath', $newPath);
+               $this->updateQuery->setParameter('newstorage', $newStorage);
                $this->updateQuery->setParameter('fileid', $fileid, IQueryBuilder::PARAM_INT);
 
                $this->updateQuery->execute();
@@ -146,12 +148,12 @@ class RepairInvalidPaths implements IRepairStep {
                foreach ($entries as $entry) {
                        $count++;
                        $calculatedPath = $entry['parent_path'] . '/' . $entry['name'];
-                       if ($newId = $this->getId($entry['storage'], $calculatedPath)) {
+                       if ($newId = $this->getId($entry['parent_storage'], $calculatedPath)) {
                                // a new entry with the correct path has already been created, reuse that one and delete the incorrect entry
                                $this->reparent($entry['fileid'], $newId);
                                $this->delete($entry['fileid']);
                        } else {
-                               $this->update($entry['fileid'], $calculatedPath);
+                               $this->update($entry['fileid'], $calculatedPath, $entry['parent_storage']);
                        }
                }
                $this->connection->commit();
index fe848b620732f04842ca6e1cd2f82f35874b85ab..b0370f5ae2d7df307c6d854b4ccd063b1f71676c 100644 (file)
@@ -36,6 +36,10 @@ class RepairInvalidPathsTest extends TestCase {
        private $storage;
        /** @var Cache */
        private $cache;
+       /** @var Temporary */
+       private $storage2;
+       /** @var Cache */
+       private $cache2;
        /** @var RepairInvalidPaths */
        private $repair;
 
@@ -44,6 +48,8 @@ class RepairInvalidPathsTest extends TestCase {
 
                $this->storage = new Temporary();
                $this->cache = $this->storage->getCache();
+               $this->storage2 = new Temporary();
+               $this->cache2 = $this->storage2->getCache();
                $config = $this->createMock(IConfig::class);
                $config->expects($this->any())
                        ->method('getSystemValue')
@@ -152,4 +158,32 @@ class RepairInvalidPathsTest extends TestCase {
                $this->assertEquals($folderId1, $this->cache->getId('foo2/bar'));
                $this->assertEquals($folderId2, $this->cache->getId('foo2/bar2'));
        }
+
+       public function testRepairNonDuplicateBetweenStorage() {
+               $this->storage->mkdir('foo/bar/asd');
+               $this->storage2->mkdir('foo2');
+               $this->storage->getScanner()->scan('');
+               $this->storage2->getScanner()->scan('');
+
+               $folderId = $this->cache->getId('foo/bar');
+               $newParentEntry = $this->cache2->get('foo2');
+               $newParentFolderId = $newParentEntry->getId();
+               // failed rename, moved entry is updated but not it's children
+               $this->cache->update($folderId, ['path' => 'foo2/bar', 'parent' => $newParentFolderId, 'storage' => $newParentEntry->getStorageId()]);
+
+               $this->assertTrue($this->cache2->inCache('foo2/bar'));
+               $this->assertTrue($this->cache->inCache('foo/bar/asd'));
+               $this->assertFalse($this->cache2->inCache('foo2/bar/asd'));
+
+               $this->assertEquals($folderId, $this->cache->get('foo/bar/asd')['parent']);
+
+               $this->repair->run($this->createMock(IOutput::class));
+
+               $this->assertTrue($this->cache2->inCache('foo2/bar'));
+               $this->assertTrue($this->cache2->inCache('foo2/bar/asd'));
+               $this->assertFalse($this->cache->inCache('foo/bar/asd'));
+
+               $this->assertEquals($folderId, $this->cache2->get('foo2/bar/asd')['parent']);
+               $this->assertEquals($folderId, $this->cache2->getId('foo2/bar'));
+       }
 }