diff options
author | Jörn Friedrich Dreyer <jfd@butonic.de> | 2014-07-31 18:27:47 +0200 |
---|---|---|
committer | Jörn Friedrich Dreyer <jfd@butonic.de> | 2014-07-31 18:27:47 +0200 |
commit | dc6180427c8b0729ce00fb1cae210e34b173e005 (patch) | |
tree | edb98dc2c8a1eb9a6c349588e9fd47726eb4429d | |
parent | 4eb2b4e1b087234499f2721bc474fa979a47f1e0 (diff) | |
parent | 1af436cb59dcb28892edc2c2edc33f178cbeb66f (diff) | |
download | nextcloud-server-dc6180427c8b0729ce00fb1cae210e34b173e005.tar.gz nextcloud-server-dc6180427c8b0729ce00fb1cae210e34b173e005.zip |
Merge pull request #10048 from owncloud/fix_search_in_shared_files
traverse folders in php to search in shared files
-rw-r--r-- | apps/files_sharing/lib/cache.php | 85 | ||||
-rw-r--r-- | apps/files_sharing/tests/cache.php | 78 |
2 files changed, 101 insertions, 62 deletions
diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 209aa49dfa4..7f7197307bd 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -275,12 +275,34 @@ class Shared_Cache extends Cache { */ public function search($pattern) { - $where = '`name` LIKE ? AND '; + $pattern = trim($pattern,'%'); - // normalize pattern - $value = $this->normalize($pattern); + $normalizedPattern = $this->normalize($pattern); - return $this->searchWithWhere($where, $value); + $result = array(); + $exploreDirs = array(''); + while (count($exploreDirs) > 0) { + $dir = array_pop($exploreDirs); + $files = $this->getFolderContents($dir); + // no results? + if (!$files) { + // maybe it's a single shared file + $file = $this->get(''); + if ($normalizedPattern === '' || stristr($file['name'], $normalizedPattern) !== false) { + $result[] = $file; + } + continue; + } + foreach ($files as $file) { + if ($normalizedPattern === '' || stristr($file['name'], $normalizedPattern) !== false) { + $result[] = $file; + } + if ($file['mimetype'] === 'httpd/unix-directory') { + $exploreDirs[] = ltrim($dir . '/' . $file['name'], '/'); + } + } + } + return $result; } @@ -297,10 +319,6 @@ class Shared_Cache extends Cache { $mimetype = null; } - // note: searchWithWhere is currently broken as it doesn't - // recurse into subdirs nor returns the correct - // file paths, so using getFolderContents() for now - $result = array(); $exploreDirs = array(''); while (count($exploreDirs) > 0) { @@ -327,57 +345,6 @@ class Shared_Cache extends Cache { } /** - * The maximum number of placeholders that can be used in an SQL query. - * Value MUST be <= 1000 for oracle: - * see ORA-01795 maximum number of expressions in a list is 1000 - * FIXME we should get this from doctrine as other DBs allow a lot more placeholders - */ - const MAX_SQL_CHUNK_SIZE = 1000; - - /** - * search for files with a custom where clause and value - * the $wherevalue will be array_merge()d with the file id chunks - * - * @param string $sqlwhere - * @param string $wherevalue - * @return array - */ - private function searchWithWhere($sqlwhere, $wherevalue, $chunksize = self::MAX_SQL_CHUNK_SIZE) { - - $ids = $this->getAll(); - - $files = array(); - - // divide into chunks - $chunks = array_chunk($ids, $chunksize); - - foreach ($chunks as $chunk) { - $placeholders = join(',', array_fill(0, count($chunk), '?')); - $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, - `encrypted`, `unencrypted_size`, `etag` - FROM `*PREFIX*filecache` WHERE ' . $sqlwhere . ' `fileid` IN (' . $placeholders . ')'; - - $stmt = \OC_DB::prepare($sql); - - $result = $stmt->execute(array_merge(array($wherevalue), $chunk)); - - while ($row = $result->fetchRow()) { - if (substr($row['path'], 0, 6) === 'files/') { - $row['path'] = substr($row['path'], 6); // remove 'files/' from path as it's relative to '/Shared' - } - $row['mimetype'] = $this->getMimetype($row['mimetype']); - $row['mimepart'] = $this->getMimetype($row['mimepart']); - if ($row['encrypted'] or ($row['unencrypted_size'] > 0 and $row['mimetype'] === 'httpd/unix-directory')) { - $row['encrypted_size'] = $row['size']; - $row['size'] = $row['unencrypted_size']; - } - $files[] = $row; - } - } - return $files; - } - - /** * get the size of a folder and set it in the cache * * @param string $path diff --git a/apps/files_sharing/tests/cache.php b/apps/files_sharing/tests/cache.php index 8472c7f1ab0..1b0fe6fdc6d 100644 --- a/apps/files_sharing/tests/cache.php +++ b/apps/files_sharing/tests/cache.php @@ -95,6 +95,80 @@ class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { parent::tearDown(); } + function searchDataProvider() { + return array( + array('%another%', + array( + array('name' => 'another too.txt', 'path' => 'subdir/another too.txt'), + array('name' => 'another.txt', 'path' => 'subdir/another.txt'), + ) + ), + array('%Another%', + array( + array('name' => 'another too.txt', 'path' => 'subdir/another too.txt'), + array('name' => 'another.txt', 'path' => 'subdir/another.txt'), + ) + ), + array('%dir%', + array( + array('name' => 'emptydir', 'path' => 'emptydir'), + array('name' => 'subdir', 'path' => 'subdir'), + array('name' => 'shareddir', 'path' => ''), + ) + ), + array('%Dir%', + array( + array('name' => 'emptydir', 'path' => 'emptydir'), + array('name' => 'subdir', 'path' => 'subdir'), + array('name' => 'shareddir', 'path' => ''), + ) + ), + array('%txt%', + array( + array('name' => 'bar.txt', 'path' => 'bar.txt'), + array('name' => 'another too.txt', 'path' => 'subdir/another too.txt'), + array('name' => 'another.txt', 'path' => 'subdir/another.txt'), + ) + ), + array('%Txt%', + array( + array('name' => 'bar.txt', 'path' => 'bar.txt'), + array('name' => 'another too.txt', 'path' => 'subdir/another too.txt'), + array('name' => 'another.txt', 'path' => 'subdir/another.txt'), + ) + ), + array('%', + array( + array('name' => 'bar.txt', 'path' => 'bar.txt'), + array('name' => 'emptydir', 'path' => 'emptydir'), + array('name' => 'subdir', 'path' => 'subdir'), + array('name' => 'another too.txt', 'path' => 'subdir/another too.txt'), + array('name' => 'another.txt', 'path' => 'subdir/another.txt'), + array('name' => 'not a text file.xml', 'path' => 'subdir/not a text file.xml'), + array('name' => 'shareddir', 'path' => ''), + ) + ), + array('%nonexistant%', + array( + ) + ), + ); + } + + /** + * we cannot use a dataProvider because that would cause the stray hook detection to remove the hooks + * that were added in setUpBeforeClass. + */ + function testSearch() { + foreach ($this->searchDataProvider() as $data) { + list($pattern, $expectedFiles) = $data; + + $results = $this->sharedStorage->getCache()->search($pattern); + + $this->verifyFiles($expectedFiles, $results); + } + + } /** * Test searching by mime type */ @@ -115,8 +189,6 @@ class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { ), ); $this->verifyFiles($check, $results); - - $this->verifyFiles($check, $results); } function testGetFolderContentsInRoot() { @@ -245,7 +317,7 @@ class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { } } } - $this->assertTrue(empty($results)); + $this->assertEquals(array(), $results); } /** |