diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 9b55666f959881223f632f533454c76c3ec4a6c2..7e0c5cb21f9d2ff4e4ace151db4c26409e8dba2d 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -251,7 +251,7 @@ class Cache { */ public function getStatus($file) { $pathHash = md5($file); - $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); + $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); $result = $query->execute(array($this->storageId, $pathHash)); if ($row = $result->fetchRow()) { if ((int)$row['size'] === -1) { @@ -267,4 +267,23 @@ class Cache { } } } + + /** + * search for files matching $pattern + * + * @param string $pattern + * @return array of file data + */ + public function search($pattern) { + $query = \OC_DB::prepare(' + SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` + FROM `*PREFIX*filecache` WHERE `name` LIKE ? AND `storage` = ?' + ); + $result = $query->execute(array($pattern, $this->storageId)); + $files = array(); + while ($row = $result->fetchRow()) { + $files[] = $row; + } + return $files; + } } diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 2b51131b20be0b9f5dc262b975fc6c0f4e7ed2bf..4031c0c5b80287355f2c6dc03e99d6dc97bf40ea 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -548,7 +548,7 @@ class Filesystem { } static public function search($query) { - return Cache\Cache::search($query); + return self::$defaultInstance->search($query); } /** diff --git a/lib/files/view.php b/lib/files/view.php index 094a7d92a4d149a47be6f5d300472f4f17473d44..ee95cce0c1d127abaaefe4d72fd198734c36da45 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -110,7 +110,7 @@ class View { */ public function getLocalFile($path) { $parent = substr($path, 0, strrpos($path, '/')); - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = Filesystem::resolvePath($path); if (Filesystem::isValidPath($parent) and $storage) { return $storage->getLocalFile($internalPath); } else { @@ -124,7 +124,7 @@ class View { */ public function getLocalFolder($path) { $parent = substr($path, 0, strrpos($path, '/')); - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = Filesystem::resolvePath($path); if (Filesystem::isValidPath($parent) and $storage) { return $storage->getLocalFolder($internalPath); } else { @@ -150,7 +150,7 @@ class View { } public function readdir($handle) { - $fsLocal = new \OC\Files\Storage\Local(array('datadir' => '/')); + $fsLocal = new Storage\Local(array('datadir' => '/')); return $fsLocal->readdir($handle); } @@ -334,8 +334,8 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - list($storage, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); - list(, $internalPath2) = \OC\Files\Filesystem::resolvePath($path2 . $postFix2); + list($storage, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); + list(, $internalPath2) = Filesystem::resolvePath($path2 . $postFix2); if ($storage) { $result = $storage->rename($internalPath1, $internalPath2); } else { @@ -345,7 +345,7 @@ class View { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); $count = \OC_Helper::streamCopy($source, $target); - list($storage1, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); + list($storage1, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); $storage1->unlink($internalPath1); $result = $count > 0; } @@ -417,8 +417,8 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - list($storage, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); - list(, $internalPath2) = \OC\Files\Filesystem::resolvePath($path2 . $postFix2); + list($storage, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); + list(, $internalPath2) = Filesystem::resolvePath($path2 . $postFix2); if ($storage) { $result = $storage->copy($internalPath1, $internalPath2); } else { @@ -553,7 +553,7 @@ class View { array(Filesystem::signal_param_path => $path) ); } - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path . $postFix); + list($storage, $internalPath) = Filesystem::resolvePath($path . $postFix); if ($storage) { $result = $storage->hash($type, $internalPath, $raw); $result = \OC_FileProxy::runPostProxies('hash', $absolutePath, $result); @@ -588,7 +588,7 @@ class View { return false; } $run = $this->runHooks($hooks, $path); - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path . $postFix); + list($storage, $internalPath) = Filesystem::resolvePath($path . $postFix); if ($run and $storage) { if (!is_null($extraParam)) { $result = $storage->$operation($internalPath, $extraParam); @@ -660,26 +660,26 @@ class View { * - versioned */ public function getFileInfo($path) { - $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $path); + $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = Filesystem::resolvePath($path); $cache = $storage->getCache(); if (!$cache->inCache($internalPath)) { $scanner = $storage->getScanner(); - $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } $data = $cache->get($internalPath); if ($data['mimetype'] === 'httpd/unix-directory') { //add the sizes of other mountpoints to the folder - $mountPoints = \OC\Files\Filesystem::getMountPoints($path); + $mountPoints = Filesystem::getMountPoints($path); foreach ($mountPoints as $mountPoint) { - $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); + $subStorage = Filesystem::getStorage($mountPoint); $subCache = $subStorage->getCache(); $rootEntry = $subCache->get(''); @@ -697,26 +697,26 @@ class View { * @return array */ public function getDirectoryContent($directory, $mimetype_filter = '') { - $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $directory); + $path = Filesystem::normalizePath($this->fakeRoot . '/' . $directory); /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = Filesystem::resolvePath($path); $cache = $storage->getCache(); if (!$cache->inCache($internalPath)) { $scanner = $storage->getScanner(); - $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders - $mountPoints = \OC\Files\Filesystem::getMountPoints($directory); + $mountPoints = Filesystem::getMountPoints($directory); $dirLength = strlen($path); foreach ($mountPoints as $mountPoint) { - $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); + $subStorage = Filesystem::getStorage($mountPoint); $subCache = $subStorage->getCache(); $rootEntry = $subCache->get(''); @@ -748,19 +748,57 @@ class View { * returns the fileid of the updated file */ public function putFileInfo($path, $data) { - $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $path); + $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = Filesystem::resolvePath($path); $cache = $storage->getCache(); if (!$cache->inCache($internalPath)) { $scanner = $storage->getScanner(); - $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } return $cache->put($internalPath, $data); } + + /** + * search for files with the name matching $query + * + * @param string $query + * @return array + */ + public function search($query) { + $files = array(); + $rootLength = strlen($this->fakeRoot); + + $mountPoint = Filesystem::getMountPoint($this->fakeRoot); + $storage = Filesystem::getStorage($mountPoint); + $cache = $storage->getCache(); + + $results = $cache->search('%' . $query . '%'); + foreach ($results as $result) { + if (substr($mountPoint . $result['path'], 0, $rootLength) === $this->fakeRoot) { + $result['path'] = substr($mountPoint . $result['path'], $rootLength); + $files[] = $result; + } + } + + $mountPoints = Filesystem::getMountPoints($this->fakeRoot); + foreach ($mountPoints as $mountPoint) { + $storage = Filesystem::getStorage($mountPoint); + $cache = $storage->getCache(); + + $relativeMountPoint = substr($mountPoint, $rootLength); + $results = $cache->search('%' . $query . '%'); + foreach ($results as $result) { + $result['path'] = $relativeMountPoint . $result['path']; + $files[] = $result; + } + } + + return $files; + } } diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 177cf1c045d083e5a83fee23ed9fb5d1256095d8..839e06e93fc446c2464791d988a5d9cda5568de7 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -111,6 +111,26 @@ class Cache extends \UnitTestCase { $this->assertEquals(\OC\Files\Cache\Cache::COMPLETE, $this->cache->getStatus('foo')); } + function testSearch() { + $file1 = 'folder'; + $file2 = 'folder/foobar'; + $file3 = 'folder/foo'; + $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'); + $fileData = array(); + $fileData['foobar'] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); + $fileData['foo'] = array('size' => 20, 'mtime' => 25, 'mimetype' => 'foo/file'); + + $this->cache->put($file1, $data1); + $this->cache->put($file2, $fileData['foobar']); + $this->cache->put($file3, $fileData['foo']); + + $this->assertEquals(2, count($this->cache->search('%foo%'))); + $this->assertEquals(1, count($this->cache->search('foo'))); + $this->assertEquals(1, count($this->cache->search('%folder%'))); + $this->assertEquals(1, count($this->cache->search('folder%'))); + $this->assertEquals(3, count($this->cache->search('%'))); + } + public function tearDown() { $this->cache->clear(); } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 051ae2516272e0cf09ae687e74fdc23e95b3220c..fc872ea5e27f1e641b3ff02990331d31fa3d7fbf 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -87,7 +87,6 @@ class View extends \PHPUnit_Framework_TestCase { Filesystem::mount($storage1, array(), '/'); Filesystem::mount($storage2, array(), '/substorage'); $textSize = strlen("dummy file data\n"); - $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); $rootView = new \OC\Files\View(''); @@ -100,6 +99,50 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals($textSize, $folderData[0]['size']); } + function testSearch() { + $storage1 = $this->getTestStorage(); + $storage2 = $this->getTestStorage(); + $storage3 = $this->getTestStorage(); + Filesystem::mount($storage1, array(), '/'); + Filesystem::mount($storage2, array(), '/substorage'); + Filesystem::mount($storage3, array(), '/folder/anotherstorage'); + + $rootView = new \OC\Files\View(''); + + $results = $rootView->search('foo'); + $this->assertEquals(6, count($results)); + $paths = array(); + foreach ($results as $result) { + $this->assertEquals($result['path'], Filesystem::normalizePath($result['path'])); + $paths[] = $result['path']; + } + $this->assertContains('/foo.txt', $paths); + $this->assertContains('/foo.png', $paths); + $this->assertContains('/substorage/foo.txt', $paths); + $this->assertContains('/substorage/foo.png', $paths); + $this->assertContains('/folder/anotherstorage/foo.txt', $paths); + $this->assertContains('/folder/anotherstorage/foo.png', $paths); + + $folderView = new \OC\Files\View('/folder'); + $results = $folderView->search('bar'); + $this->assertEquals(2, count($results)); + $paths = array(); + foreach ($results as $result) { + $paths[] = $result['path']; + } + $this->assertContains('/anotherstorage/folder/bar.txt', $paths); + $this->assertContains('/bar.txt', $paths); + + $results = $folderView->search('foo'); + $this->assertEquals(2, count($results)); + $paths = array(); + foreach ($results as $result) { + $paths[] = $result['path']; + } + $this->assertContains('/anotherstorage/foo.txt', $paths); + $this->assertContains('/anotherstorage/foo.png', $paths); + } + /** * @param bool $scan * @return \OC\Files\Storage\Storage