/** * get the stored metadata of a file or folder * * @param string /int $file * @return array|false */ public function get($file) { $result = $this->cache->get($file); if ($result) { $result = $this->formatCacheEntry($result); } return $result; }
/** * check $path for updates and update if needed * * @param string $path * @param ICacheEntry|null $cachedEntry * @return boolean true if path was updated */ public function checkUpdate($path, $cachedEntry = null) { if (is_null($cachedEntry)) { $cachedEntry = $this->cache->get($path); } if ($this->needsUpdate($path, $cachedEntry)) { $this->update($path, $cachedEntry); return true; } else { return false; } }
/** * scan a single file and store it in the cache * * @param string $file * @param int $reuseExisting * @return array an array of metadata of the scanned file */ public function scanFile($file, $reuseExisting = 0) { if (!self::isPartialFile($file) and !Filesystem::isFileBlacklisted($file)) { $this->emit('\\OC\\Files\\Cache\\Scanner', 'scanFile', array($file, $this->storageId)); \OC_Hook::emit('\\OC\\Files\\Cache\\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId)); $data = $this->getData($file); if ($data) { $parent = dirname($file); if ($parent === '.' or $parent === '/') { $parent = ''; } $parentId = $this->cache->getId($parent); // scan the parent if it's not in the cache (id -1) and the current file is not the root folder if ($file and $parentId === -1) { $parentData = $this->scanFile($parent); $parentId = $parentData['fileid']; } if ($parent) { $data['parent'] = $parentId; } $cacheData = $this->cache->get($file); if ($cacheData and $reuseExisting) { // prevent empty etag if (empty($cacheData['etag'])) { $etag = $data['etag']; } else { $etag = $cacheData['etag']; } // only reuse data if the file hasn't explicitly changed if (isset($data['storage_mtime']) && isset($cacheData['storage_mtime']) && $data['storage_mtime'] === $cacheData['storage_mtime']) { $data['mtime'] = $cacheData['mtime']; if ($reuseExisting & self::REUSE_SIZE && $data['size'] === -1) { $data['size'] = $cacheData['size']; } if ($reuseExisting & self::REUSE_ETAG) { $data['etag'] = $etag; } } // Only update metadata that has changed $newData = array_diff_assoc($data, $cacheData); if (isset($newData['etag'])) { $cacheDataString = print_r($cacheData, true); $dataString = print_r($data, true); \OCP\Util::writeLog('OC\\Files\\Cache\\Scanner', "!!! No reuse of etag for '{$file}' !!! \ncache: {$cacheDataString} \ndata: {$dataString}", \OCP\Util::DEBUG); } } else { $newData = $data; } if (!empty($newData)) { $data['fileid'] = $this->addToCache($file, $newData); $this->emit('\\OC\\Files\\Cache\\Scanner', 'postScanFile', array($file, $this->storageId)); \OC_Hook::emit('\\OC\\Files\\Cache\\Scanner', 'post_scan_file', array('path' => $file, 'storage' => $this->storageId)); } } else { $this->removeFromCache($file); } return $data; } return null; }
/** * this test shows that there is no bug if we use the normalizer */ public function testWithNormalizer() { if (!class_exists('Patchwork\\PHP\\Shim\\Normalizer')) { $this->markTestSkipped('The 3rdparty Normalizer extension is not available.'); return; } // folder name "Schön" with U+00F6 (normalized) $folderWith00F6 = "Schön"; // folder name "Schön" with U+0308 (un-normalized) $folderWith0308 = "Schön"; $data = array('size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory'); // put root folder $this->assertFalse($this->cache->get('folder')); $this->assertGreaterThan(0, $this->cache->put('folder', $data)); // put un-normalized folder $this->assertFalse($this->cache->get('folder/' . $folderWith0308)); $this->assertGreaterThan(0, $this->cache->put('folder/' . $folderWith0308, $data)); // get un-normalized folder by name $unNormalizedFolderName = $this->cache->get('folder/' . $folderWith0308); // check if folder name was normalized $this->assertEquals($folderWith00F6, $unNormalizedFolderName['name']); // put normalized folder $this->assertTrue(is_array($this->cache->get('folder/' . $folderWith00F6))); $this->assertGreaterThan(0, $this->cache->put('folder/' . $folderWith00F6, $data)); // at this point we should have only one folder named "Schön" $this->assertEquals(1, count($this->cache->getFolderContents('folder'))); }
public function testTouch() { $rootCachedData = $this->cache->get(''); $fooCachedData = $this->cache->get('foo.txt'); Filesystem::touch('foo.txt'); $cachedData = $this->cache->get('foo.txt'); $this->assertInternalType('string', $fooCachedData['etag']); $this->assertInternalType('string', $cachedData['etag']); $this->assertGreaterThanOrEqual($fooCachedData['mtime'], $cachedData['mtime']); $cachedData = $this->cache->get(''); $this->assertInternalType('string', $rootCachedData['etag']); $this->assertInternalType('string', $cachedData['etag']); $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']); $this->assertGreaterThanOrEqual($rootCachedData['mtime'], $cachedData['mtime']); $rootCachedData = $cachedData; $time = 1371006070; $barCachedData = $this->cache->get('folder/bar.txt'); $folderCachedData = $this->cache->get('folder'); $this->cache->put('', ['mtime' => $time - 100]); Filesystem::touch('folder/bar.txt', $time); $cachedData = $this->cache->get('folder/bar.txt'); $this->assertInternalType('string', $barCachedData['etag']); $this->assertInternalType('string', $cachedData['etag']); $this->assertNotSame($barCachedData['etag'], $cachedData['etag']); $this->assertEquals($time, $cachedData['mtime']); $cachedData = $this->cache->get('folder'); $this->assertInternalType('string', $folderCachedData['etag']); $this->assertInternalType('string', $cachedData['etag']); $this->assertNotSame($folderCachedData['etag'], $cachedData['etag']); $cachedData = $this->cache->get(''); $this->assertInternalType('string', $rootCachedData['etag']); $this->assertInternalType('string', $cachedData['etag']); $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']); $this->assertEquals($time, $cachedData['mtime']); }
public function testTouchWithMountPoints() { $storage2 = new \OC\Files\Storage\Temporary(array()); $cache2 = $storage2->getCache(); Filesystem::mount($storage2, array(), '/' . self::$user . '/files/folder/substorage'); Filesystem::file_put_contents('folder/substorage/foo.txt', 'asd'); $this->assertTrue($cache2->inCache('foo.txt')); $folderCachedData = $this->cache->get('folder'); $substorageCachedData = $cache2->get(''); $fooCachedData = $cache2->get('foo.txt'); $cachedData = $cache2->get('foo.txt'); $time = 1371006070; $this->cache->put('folder', ['mtime' => $time - 100]); Filesystem::touch('folder/substorage/foo.txt', $time); $cachedData = $cache2->get('foo.txt'); $this->assertInternalType('string', $fooCachedData['etag']); $this->assertInternalType('string', $cachedData['etag']); $this->assertNotSame($fooCachedData['etag'], $cachedData['etag']); $this->assertEquals($time, $cachedData['mtime']); $cachedData = $cache2->get(''); $this->assertInternalType('string', $substorageCachedData['etag']); $this->assertInternalType('string', $cachedData['etag']); $this->assertNotSame($substorageCachedData['etag'], $cachedData['etag']); $cachedData = $this->cache->get('folder'); $this->assertInternalType('string', $folderCachedData['etag']); $this->assertInternalType('string', $cachedData['etag']); $this->assertNotSame($folderCachedData['etag'], $cachedData['etag']); $this->assertEquals($time, $cachedData['mtime']); }
public function get($file) { $result = parent::get($file); $result['displayname_owner'] = $this->remoteUser . '@' . $this->remote; if (!$file || $file === '') { $result['is_share_mount_point'] = true; $mountPoint = rtrim($this->storage->getMountPoint()); $result['name'] = basename($mountPoint); } return $result; }
public function testMoveFolderCrossStorage() { $storage2 = new Temporary(array()); $cache2 = $storage2->getCache(); Filesystem::mount($storage2, array(), '/bar'); $this->storage->mkdir('foo'); $this->storage->mkdir('foo/bar'); $this->storage->file_put_contents('foo/foo.txt', 'qwerty'); $this->storage->file_put_contents('foo/bar.txt', 'foo'); $this->storage->file_put_contents('foo/bar/bar.txt', 'qwertyuiop'); $this->storage->getScanner()->scan(''); $this->assertTrue($this->cache->inCache('foo')); $this->assertTrue($this->cache->inCache('foo/foo.txt')); $this->assertTrue($this->cache->inCache('foo/bar.txt')); $this->assertTrue($this->cache->inCache('foo/bar')); $this->assertTrue($this->cache->inCache('foo/bar/bar.txt')); $cached = []; $cached[] = $this->cache->get('foo'); $cached[] = $this->cache->get('foo/foo.txt'); $cached[] = $this->cache->get('foo/bar.txt'); $cached[] = $this->cache->get('foo/bar'); $cached[] = $this->cache->get('foo/bar/bar.txt'); // add extension to trigger the possible mimetype change $this->view->rename('/foo', '/bar/foo.b'); $this->assertFalse($this->cache->inCache('foo')); $this->assertFalse($this->cache->inCache('foo/foo.txt')); $this->assertFalse($this->cache->inCache('foo/bar.txt')); $this->assertFalse($this->cache->inCache('foo/bar')); $this->assertFalse($this->cache->inCache('foo/bar/bar.txt')); $this->assertTrue($cache2->inCache('foo.b')); $this->assertTrue($cache2->inCache('foo.b/foo.txt')); $this->assertTrue($cache2->inCache('foo.b/bar.txt')); $this->assertTrue($cache2->inCache('foo.b/bar')); $this->assertTrue($cache2->inCache('foo.b/bar/bar.txt')); $cachedTarget = []; $cachedTarget[] = $cache2->get('foo.b'); $cachedTarget[] = $cache2->get('foo.b/foo.txt'); $cachedTarget[] = $cache2->get('foo.b/bar.txt'); $cachedTarget[] = $cache2->get('foo.b/bar'); $cachedTarget[] = $cache2->get('foo.b/bar/bar.txt'); foreach ($cached as $i => $old) { $new = $cachedTarget[$i]; $this->assertEquals($old['mtime'], $new['mtime']); $this->assertEquals($old['size'], $new['size']); $this->assertEquals($old['etag'], $new['etag']); $this->assertEquals($old['fileid'], $new['fileid']); $this->assertEquals($old['mimetype'], $new['mimetype']); } }
/** * Returns the sizes of the path and its parent dirs in a hash * where the key is the path and the value is the size. * @param string $path */ function getOwnerDirSizes($path) { $result = array(); while ($path != '' && $path != '' && $path != '.') { $cachedData = $this->ownerCache->get($path); $result[$path] = $cachedData['size']; $path = dirname($path); } $cachedData = $this->ownerCache->get(''); $result[''] = $cachedData['size']; return $result; }
/** * @param string $path * @return ICacheEntry */ public function get($path) { $data = parent::get($path); if ($path === '' or $path === '/') { // only the size of the "files" dir counts $filesData = parent::get('files'); if (isset($filesData['size'])) { $data['size'] = $filesData['size']; } } return $data; }
public function testNoReuseOfFileId() { $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain'); $this->cache->put('somefile.txt', $data1); $info = $this->cache->get('somefile.txt'); $fileId = $info['fileid']; $this->cache->remove('somefile.txt'); $data2 = array('size' => 200, 'mtime' => 100, 'mimetype' => 'text/plain'); $this->cache->put('anotherfile.txt', $data2); $info2 = $this->cache->get('anotherfile.txt'); $fileId2 = $info2['fileid']; $this->assertNotEquals($fileId, $fileId2); }
public function testMoveDisabled() { $this->storage->file_put_contents('foo.txt', 'qwerty'); $this->updater->update('foo.txt'); $this->assertTrue($this->cache->inCache('foo.txt')); $this->assertFalse($this->cache->inCache('bar.txt')); $cached = $this->cache->get('foo.txt'); $this->storage->rename('foo.txt', 'bar.txt'); $this->assertTrue($this->cache->inCache('foo.txt')); $this->assertFalse($this->cache->inCache('bar.txt')); $this->updater->disable(); $this->updater->rename('foo.txt', 'bar.txt'); $this->assertTrue($this->cache->inCache('foo.txt')); $this->assertFalse($this->cache->inCache('bar.txt')); }
/** * Test searching by tag for multiple sections of the tree */ function testSearchByTagTree() { $userId = \OC::$server->getUserSession()->getUser()->getUId(); $this->sharedStorage->mkdir('subdir/emptydir'); $this->sharedStorage->mkdir('subdir/emptydir2'); $this->ownerStorage->getScanner()->scan(''); $allIds = array($this->sharedCache->get('')['fileid'], $this->sharedCache->get('bar.txt')['fileid'], $this->sharedCache->get('subdir/another too.txt')['fileid'], $this->sharedCache->get('subdir/not a text file.xml')['fileid'], $this->sharedCache->get('subdir/another.txt')['fileid'], $this->sharedCache->get('subdir/emptydir')['fileid'], $this->sharedCache->get('subdir/emptydir2')['fileid']); $tagManager = \OC::$server->getTagManager()->load('files', null, null, $userId); foreach ($allIds as $id) { $tagManager->tagAs($id, 'tag1'); } $results = $this->sharedStorage->getCache()->searchByTag('tag1', $userId); $check = array(array('name' => 'shareddir', 'path' => ''), array('name' => 'bar.txt', 'path' => 'bar.txt'), array('name' => 'another.txt', 'path' => 'subdir/another.txt'), array('name' => 'another too.txt', 'path' => 'subdir/another too.txt'), array('name' => 'emptydir', 'path' => 'subdir/emptydir'), array('name' => 'emptydir2', 'path' => 'subdir/emptydir2'), array('name' => 'not a text file.xml', 'path' => 'subdir/not a text file.xml')); $this->verifyFiles($check, $results); $tagManager->delete(array('tag1')); }
/** * Test bogus paths with leading or doubled slashes * * @dataProvider bogusPathNamesProvider */ public function testBogusPaths($bogusPath, $fixedBogusPath) { $data = array('size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory'); // put root folder $this->assertFalse($this->cache->get('')); $parentId = $this->cache->put('', $data); $this->assertGreaterThan(0, $parentId); $this->assertGreaterThan(0, $this->cache->put($bogusPath, $data)); $newData = $this->cache->get($fixedBogusPath); $this->assertNotFalse($newData); $this->assertEquals($fixedBogusPath, $newData['path']); // parent is the correct one, resolved properly (they used to not be) $this->assertEquals($parentId, $newData['parent']); $newDataFromBogus = $this->cache->get($bogusPath); // same entry $this->assertEquals($newData, $newDataFromBogus); }
public function testRepairParentShallow() { $this->fillTestFolders(); $this->scanner->scan(''); $this->assertTrue($this->cache->inCache('folder/bar.txt')); $oldFolderId = $this->cache->getId('folder'); // delete the folder without removing the childs $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `fileid` = ?'; \OC_DB::executeAudited($sql, array($oldFolderId)); $cachedData = $this->cache->get('folder/bar.txt'); $this->assertEquals($oldFolderId, $cachedData['parent']); $this->assertFalse($this->cache->inCache('folder')); $this->scanner->scan('folder', \OC\Files\Cache\Scanner::SCAN_SHALLOW); $this->assertTrue($this->cache->inCache('folder')); $newFolderId = $this->cache->getId('folder'); $this->assertNotEquals($oldFolderId, $newFolderId); $cachedData = $this->cache->get('folder/bar.txt'); $this->assertEquals($newFolderId, $cachedData['parent']); }
public function testMove() { $this->storage->file_put_contents('foo.txt', 'qwerty'); $this->updater->update('foo.txt'); $this->assertTrue($this->cache->inCache('foo.txt')); $this->assertFalse($this->cache->inCache('bar.txt')); $cached = $this->cache->get('foo.txt'); $this->storage->rename('foo.txt', 'bar.txt'); $this->assertTrue($this->cache->inCache('foo.txt')); $this->assertFalse($this->cache->inCache('bar.txt')); $this->updater->rename('foo.txt', 'bar.txt'); $this->assertFalse($this->cache->inCache('foo.txt')); $this->assertTrue($this->cache->inCache('bar.txt')); $cachedTarget = $this->cache->get('bar.txt'); $this->assertEquals($cached['etag'], $cachedTarget['etag']); $this->assertEquals($cached['mtime'], $cachedTarget['mtime']); $this->assertEquals($cached['size'], $cachedTarget['size']); $this->assertEquals($cached['fileid'], $cachedTarget['fileid']); }
/** * Remove $path from the cache and update the size, etag and mtime of the parent folders * * @param string $path */ public function remove($path) { if (!$this->enabled or Scanner::isPartialFile($path)) { return; } $parent = dirname($path); if ($parent === '.') { $parent = ''; } $entry = $this->cache->get($path); $this->cache->remove($path); $this->correctParentStorageMtime($path); if ($entry instanceof ICacheEntry) { $this->propagator->propagateChange($path, time(), -$entry->getSize()); } else { $this->propagator->propagateChange($path, time()); if ($this->cache instanceof Cache) { $this->cache->correctFolderSize($parent); } } }
/** * @param string $name * @dataProvider escapingProvider */ public function testEscaping($name) { $data = array('size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain'); $this->cache->put($name, $data); $this->assertTrue($this->cache->inCache($name)); $retrievedData = $this->cache->get($name); foreach ($data as $key => $value) { $this->assertEquals($value, $retrievedData[$key]); } $this->cache->move($name, $name . 'asd'); $this->assertFalse($this->cache->inCache($name)); $this->assertTrue($this->cache->inCache($name . 'asd')); $this->cache->remove($name . 'asd'); $this->assertFalse($this->cache->inCache($name . 'asd')); $folderData = array('size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory'); $this->cache->put($name, $folderData); $this->cache->put('other', $folderData); $childs = ['asd', 'bar', 'foo', 'sub/folder']; $this->cache->put($name . '/sub', $folderData); $this->cache->put('other/sub', $folderData); foreach ($childs as $child) { $this->cache->put($name . '/' . $child, $data); $this->cache->put('other/' . $child, $data); $this->assertTrue($this->cache->inCache($name . '/' . $child)); } $this->cache->move($name, $name . 'asd'); foreach ($childs as $child) { $this->assertTrue($this->cache->inCache($name . 'asd/' . $child)); $this->assertTrue($this->cache->inCache('other/' . $child)); } foreach ($childs as $child) { $this->cache->remove($name . 'asd/' . $child); $this->assertFalse($this->cache->inCache($name . 'asd/' . $child)); $this->assertTrue($this->cache->inCache('other/' . $child)); } }
/** * scan a single file and store it in the cache * * @param string $file * @param int $reuseExisting * @param bool $parentExistsInCache * @return array with metadata of the scanned file */ public function scanFile($file, $reuseExisting = 0, $parentExistsInCache = false) { if (!self::isPartialFile($file) and !Filesystem::isFileBlacklisted($file)) { $this->emit('\\OC\\Files\\Cache\\Scanner', 'scanFile', array($file, $this->storageId)); \OC_Hook::emit('\\OC\\Files\\Cache\\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId)); $data = $this->getData($file); if ($data) { if ($file and !$parentExistsInCache) { $parent = dirname($file); if ($parent === '.' or $parent === '/') { $parent = ''; } if (!$this->cache->inCache($parent)) { $this->scanFile($parent); } } $newData = $data; $cacheData = $this->cache->get($file); if ($cacheData) { if (isset($cacheData['fileid'])) { $this->permissionsCache->remove($cacheData['fileid']); } if ($reuseExisting) { // prevent empty etag $etag = $cacheData['etag']; $propagateETagChange = false; if (empty($etag)) { $etag = $data['etag']; $propagateETagChange = true; } // only reuse data if the file hasn't explicitly changed if (isset($data['mtime']) && isset($cacheData['mtime']) && $data['mtime'] === $cacheData['mtime']) { if ($reuseExisting & self::REUSE_SIZE && $data['size'] === -1) { $data['size'] = $cacheData['size']; } if ($reuseExisting & self::REUSE_ETAG) { $data['etag'] = $etag; if ($propagateETagChange) { $parent = $file; while ($parent !== '') { $parent = dirname($parent); if ($parent === '.') { $parent = ''; } $parentCacheData = $this->cache->get($parent); $this->cache->update($parentCacheData['fileid'], array('etag' => $this->storage->getETag($parent))); } } } } // Only update metadata that has changed $newData = array_diff_assoc($data, $cacheData); if (isset($newData['etag'])) { $cacheDataString = print_r($cacheData, true); $dataString = print_r($data, true); \OCP\Util::writeLog('OC\\Files\\Cache\\Scanner', "!!! No reuse of etag for '{$file}' !!! \ncache: {$cacheDataString} \ndata: {$dataString}", \OCP\Util::DEBUG); } } } if (!empty($newData)) { $this->cache->put($file, $newData); $this->emit('\\OC\\Files\\Cache\\Scanner', 'postScanFile', array($file, $this->storageId)); \OC_Hook::emit('\\OC\\Files\\Cache\\Scanner', 'post_scan_file', array('path' => $file, 'storage' => $this->storageId)); } } else { $this->cache->remove($file); } return $data; } return null; }
/** * scan a single file and store it in the cache * * @param string $file * @param int $reuseExisting * @param int $parentId * @param array | null $cacheData existing data in the cache for the file to be scanned * @param bool $lock set to false to disable getting an additional read lock during scanning * @return array an array of metadata of the scanned file * @throws \OC\ServerNotAvailableException * @throws \OCP\Lock\LockedException */ public function scanFile($file, $reuseExisting = 0, $parentId = -1, $cacheData = null, $lock = true) { // only proceed if $file is not a partial file nor a blacklisted file if (!self::isPartialFile($file) and !Filesystem::isFileBlacklisted($file)) { //acquire a lock if ($lock) { if ($this->storage->instanceOfStorage('\\OCP\\Files\\Storage\\ILockingStorage')) { $this->storage->acquireLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider); } } $data = $this->getData($file); if ($data) { // pre-emit only if it was a file. By that we avoid counting/treating folders as files if ($data['mimetype'] !== 'httpd/unix-directory') { $this->emit('\\OC\\Files\\Cache\\Scanner', 'scanFile', array($file, $this->storageId)); \OC_Hook::emit('\\OC\\Files\\Cache\\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId)); } $parent = dirname($file); if ($parent === '.' or $parent === '/') { $parent = ''; } if ($parentId === -1) { $parentId = $this->cache->getId($parent); } // scan the parent if it's not in the cache (id -1) and the current file is not the root folder if ($file and $parentId === -1) { $parentData = $this->scanFile($parent); $parentId = $parentData['fileid']; } if ($parent) { $data['parent'] = $parentId; } if (is_null($cacheData)) { /** @var CacheEntry $cacheData */ $cacheData = $this->cache->get($file); } if ($cacheData and $reuseExisting and isset($cacheData['fileid'])) { // prevent empty etag if (empty($cacheData['etag'])) { $etag = $data['etag']; } else { $etag = $cacheData['etag']; } $fileId = $cacheData['fileid']; $data['fileid'] = $fileId; // only reuse data if the file hasn't explicitly changed if (isset($data['storage_mtime']) && isset($cacheData['storage_mtime']) && $data['storage_mtime'] === $cacheData['storage_mtime']) { $data['mtime'] = $cacheData['mtime']; if ($reuseExisting & self::REUSE_SIZE && $data['size'] === -1) { $data['size'] = $cacheData['size']; } if ($reuseExisting & self::REUSE_ETAG) { $data['etag'] = $etag; } } // Only update metadata that has changed $newData = array_diff_assoc($data, $cacheData->getData()); } else { $newData = $data; $fileId = -1; } if (!empty($newData)) { // Reset the checksum if the data has changed $newData['checksum'] = ''; $data['fileid'] = $this->addToCache($file, $newData, $fileId); } if (isset($cacheData['size'])) { $data['oldSize'] = $cacheData['size']; } else { $data['oldSize'] = 0; } if (isset($cacheData['encrypted'])) { $data['encrypted'] = $cacheData['encrypted']; } // post-emit only if it was a file. By that we avoid counting/treating folders as files if ($data['mimetype'] !== 'httpd/unix-directory') { $this->emit('\\OC\\Files\\Cache\\Scanner', 'postScanFile', array($file, $this->storageId)); \OC_Hook::emit('\\OC\\Files\\Cache\\Scanner', 'post_scan_file', array('path' => $file, 'storage' => $this->storageId)); } } else { $this->removeFromCache($file); } //release the acquired lock if ($lock) { if ($this->storage->instanceOfStorage('\\OCP\\Files\\Storage\\ILockingStorage')) { $this->storage->releaseLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider); } } if ($data && !isset($data['encrypted'])) { $data['encrypted'] = false; } return $data; } return null; }
/** * scan a single file and store it in the cache * * @param string $file * @param int $reuseExisting * @param int $parentId * @param array | null $cacheData existing data in the cache for the file to be scanned * @param bool $lock set to false to disable getting an additional read lock during scanning * @return array an array of metadata of the scanned file * @throws \OC\ServerNotAvailableException * @throws \OCP\Lock\LockedException */ public function scanFile($file, $reuseExisting = 0, $parentId = -1, $cacheData = null, $lock = true) { if (!self::isPartialFile($file) and !Filesystem::isFileBlacklisted($file)) { if ($lock) { $this->storage->acquireLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider); } $this->emit('\\OC\\Files\\Cache\\Scanner', 'scanFile', array($file, $this->storageId)); \OC_Hook::emit('\\OC\\Files\\Cache\\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId)); $data = $this->getData($file); if ($data) { $parent = dirname($file); if ($parent === '.' or $parent === '/') { $parent = ''; } if ($parentId === -1) { $parentId = $this->cache->getId($parent); } // scan the parent if it's not in the cache (id -1) and the current file is not the root folder if ($file and $parentId === -1) { $parentData = $this->scanFile($parent); $parentId = $parentData['fileid']; } if ($parent) { $data['parent'] = $parentId; } if (is_null($cacheData)) { $cacheData = $this->cache->get($file); } if ($cacheData and $reuseExisting and isset($cacheData['fileid'])) { // prevent empty etag if (empty($cacheData['etag'])) { $etag = $data['etag']; } else { $etag = $cacheData['etag']; } $fileId = $cacheData['fileid']; $data['fileid'] = $fileId; // only reuse data if the file hasn't explicitly changed if (isset($data['storage_mtime']) && isset($cacheData['storage_mtime']) && $data['storage_mtime'] === $cacheData['storage_mtime']) { $data['mtime'] = $cacheData['mtime']; if ($reuseExisting & self::REUSE_SIZE && $data['size'] === -1) { $data['size'] = $cacheData['size']; } if ($reuseExisting & self::REUSE_ETAG) { $data['etag'] = $etag; } } // Only update metadata that has changed $newData = array_diff_assoc($data, $cacheData); } else { $newData = $data; $fileId = -1; } if (!empty($newData)) { $data['fileid'] = $this->addToCache($file, $newData, $fileId); } $this->emit('\\OC\\Files\\Cache\\Scanner', 'postScanFile', array($file, $this->storageId)); \OC_Hook::emit('\\OC\\Files\\Cache\\Scanner', 'post_scan_file', array('path' => $file, 'storage' => $this->storageId)); } else { $this->removeFromCache($file); } if ($lock) { $this->storage->releaseLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider); } return $data; } return null; }
/** * Move a file or folder in the cache * * @param \OC\Files\Cache\Cache $sourceCache * @param string $sourcePath * @param string $targetPath * @throws \OC\DatabaseException */ public function moveFromCache(Cache $sourceCache, $sourcePath, $targetPath) { // normalize source and target $sourcePath = $this->normalize($sourcePath); $targetPath = $this->normalize($targetPath); $sourceData = $sourceCache->get($sourcePath); $sourceId = $sourceData['fileid']; $newParentId = $this->getParentId($targetPath); list($sourceStorageId, $sourcePath) = $sourceCache->getMoveInfo($sourcePath); list($targetStorageId, $targetPath) = $this->getMoveInfo($targetPath); // sql for final update $moveSql = 'UPDATE `*PREFIX*filecache` SET `storage` = ?, `path` = ?, `path_hash` = ?, `name` = ?, `parent` =? WHERE `fileid` = ?'; if ($sourceData['mimetype'] === 'httpd/unix-directory') { //find all child entries $sql = 'SELECT `path`, `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path` LIKE ?'; $result = $this->connection->executeQuery($sql, [$sourceStorageId, $this->connection->escapeLikeParameter($sourcePath) . '/%']); $childEntries = $result->fetchAll(); $sourceLength = strlen($sourcePath); $this->connection->beginTransaction(); $query = $this->connection->prepare('UPDATE `*PREFIX*filecache` SET `storage` = ?, `path` = ?, `path_hash` = ? WHERE `fileid` = ?'); foreach ($childEntries as $child) { $newTargetPath = $targetPath . substr($child['path'], $sourceLength); $query->execute([$targetStorageId, $newTargetPath, md5($newTargetPath), $child['fileid']]); } $this->connection->executeQuery($moveSql, [$targetStorageId, $targetPath, md5($targetPath), basename($targetPath), $newParentId, $sourceId]); $this->connection->commit(); } else { $this->connection->executeQuery($moveSql, [$targetStorageId, $targetPath, md5($targetPath), basename($targetPath), $newParentId, $sourceId]); } }
public function get($path) { $data = parent::get($path); $data['permissions'] &= \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_SHARE; return $data; }