diff options
-rw-r--r-- | apps/files_encryption/lib/util.php | 13 | ||||
-rw-r--r-- | apps/files_sharing/lib/cache.php | 80 | ||||
-rw-r--r-- | lib/private/files/cache/updater.php | 20 | ||||
-rw-r--r-- | tests/lib/files/cache/updater.php | 34 |
4 files changed, 106 insertions, 41 deletions
diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 0d34af043a1..5e855abd973 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -205,7 +205,7 @@ class Util { $this->userId, 'server-side', 0, - 0 + self::MIGRATION_OPEN ); $query = \OCP\DB::prepare($sql); $query->execute($args); @@ -1285,6 +1285,17 @@ class Util { // If no record is found if (empty($migrationStatus)) { \OCP\Util::writeLog('Encryption library', "Could not get migration status for " . $this->userId . ", no record found", \OCP\Util::ERROR); + // insert missing entry in DB with status open + $sql = 'INSERT INTO `*PREFIX*encryption` (`uid`,`mode`,`recovery_enabled`,`migration_status`) VALUES (?,?,?,?)'; + $args = array( + $this->userId, + 'server-side', + 0, + self::MIGRATION_OPEN + ); + $query = \OCP\DB::prepare($sql); + $query->execute($args); + return self::MIGRATION_OPEN; // If a record is found } else { diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 123268e240a..6b66edcacc5 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -228,69 +228,73 @@ class Shared_Cache extends Cache { */ public function search($pattern) { + $where = '`name` LIKE ? AND '; + // normalize pattern - $pattern = $this->normalize($pattern); + $value = $this->normalize($pattern); - $ids = $this->getAll(); + return $this->searchWithWhere($where, $value); - $files = array(); - - // divide into 1k chunks - $chunks = array_chunk($ids, 1000); - - 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 `name` LIKE ? AND `fileid` IN (' . $placeholders . ')'; - - $result = \OC_DB::executeAudited($sql, array_merge(array($pattern), $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']); - $files[] = $row; - } - } - return $files; } /** * search for files by mimetype * - * @param string $part1 - * @param string $part2 + * @param string $mimetype * @return array */ public function searchByMime($mimetype) { + if (strpos($mimetype, '/')) { - $where = '`mimetype` = ?'; + $where = '`mimetype` = ? AND '; } else { - $where = '`mimepart` = ?'; + $where = '`mimepart` = ? AND '; } - $mimetype = $this->getMimetypeId($mimetype); + + $value = $this->getMimetypeId($mimetype); + + return $this->searchWithWhere($where, $value); + + } + + /** + * 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 1k chunks - $chunks = array_chunk($ids, 1000); + // divide into chunks + $chunks = array_chunk($ids, $chunksize); foreach ($chunks as $chunk) { - $placeholders = join(',', array_fill(0, count($ids), '?')); + $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 ' . $where . ' AND `fileid` IN (' . $placeholders . ')'; + FROM `*PREFIX*filecache` WHERE ' . $sqlwhere . ' `fileid` IN (' . $placeholders . ')'; - $result = \OC_DB::executeAudited($sql, array_merge(array($mimetype), $chunk)); + $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' + 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']); diff --git a/lib/private/files/cache/updater.php b/lib/private/files/cache/updater.php index 48fb3ba6c5c..da223567001 100644 --- a/lib/private/files/cache/updater.php +++ b/lib/private/files/cache/updater.php @@ -7,6 +7,7 @@ */ namespace OC\Files\Cache; + use OCP\Util; /** @@ -42,6 +43,7 @@ class Updater { $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); $cache->correctFolderSize($internalPath); self::correctFolder($path, $storage->filemtime($internalPath)); + self::correctParentStorageMtime($storage, $internalPath); } } @@ -61,6 +63,7 @@ class Updater { $cache->remove($internalPath); $cache->correctFolderSize($internalPath); self::correctFolder($path, time()); + self::correctParentStorageMtime($storage, $internalPath); } } @@ -87,6 +90,8 @@ class Updater { $cache->correctFolderSize($internalTo); self::correctFolder($from, time()); self::correctFolder($to, time()); + self::correctParentStorageMtime($storageFrom, $internalFrom); + self::correctParentStorageMtime($storageTo, $internalTo); } else { self::deleteUpdate($from); self::writeUpdate($to); @@ -152,6 +157,21 @@ class Updater { } /** + * update the storage_mtime of the parent + * + * @param \OC\Files\Storage\Storage $storage + * @param string $internalPath + */ + static private function correctParentStorageMtime($storage, $internalPath) { + $cache = $storage->getCache(); + $parentId = $cache->getParentId($internalPath); + $parent = dirname($internalPath); + if ($parentId != -1) { + $cache->update($parentId, array('storage_mtime' => $storage->filemtime($parent))); + } + } + + /** * @param array $params */ static public function writeHook($params) { diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php index 9c1c6f8d18f..e3d3aae818d 100644 --- a/tests/lib/files/cache/updater.php +++ b/tests/lib/files/cache/updater.php @@ -9,6 +9,7 @@ namespace Test\Files\Cache; use \OC\Files\Filesystem as Filesystem; +use OC\Files\Storage\Temporary; class Updater extends \PHPUnit_Framework_TestCase { /** @@ -251,7 +252,6 @@ class Updater extends \PHPUnit_Framework_TestCase { $cachedData = $this->cache->get('folder'); $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']); - $this->assertEquals($time, $cachedData['mtime']); $cachedData = $this->cache->get(''); $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); @@ -276,11 +276,41 @@ class Updater extends \PHPUnit_Framework_TestCase { $cachedData = $cache2->get(''); $this->assertNotEquals($substorageCachedData['etag'], $cachedData['etag']); - $this->assertEquals($time, $cachedData['mtime']); $cachedData = $this->cache->get('folder'); $this->assertNotEquals($folderCachedData['etag'], $cachedData['etag']); $this->assertEquals($time, $cachedData['mtime']); } + public function testUpdatePermissionsOnRescanOnlyForUpdatedFile() { + $permissionsCache = $this->storage->getPermissionsCache(); + $scanner = $this->storage->getScanner(); + $scanner->scan(''); + $cache = $this->storage->getCache(); + $loggedInUser = \OC_User::getUser(); + \OC_User::setUserId(self::$user); + FileSystem::getDirectoryContent('/'); + $past = time() - 600; + $cache->put('', array('storage_mtime' => $past)); + + $this->assertNotEquals(-1, $permissionsCache->get($cache->getId('foo.txt'), self::$user)); + $this->assertNotEquals(-1, $permissionsCache->get($cache->getId('foo.png'), self::$user)); + + $permissionsCache->set($cache->getId('foo.png'), self::$user, 15); + FileSystem::file_put_contents('/foo.txt', 'asd'); + + $this->assertEquals(-1, $permissionsCache->get($cache->getId('foo.txt'), self::$user)); + $this->assertEquals(15, $permissionsCache->get($cache->getId('foo.png'), self::$user)); + + FileSystem::getDirectoryContent('/'); + + $this->assertEquals(15, $permissionsCache->get($cache->getId('foo.png'), self::$user)); + + FileSystem::file_put_contents('/qwerty.txt', 'asd'); + FileSystem::getDirectoryContent('/'); + + $this->assertEquals(15, $permissionsCache->get($cache->getId('foo.png'), self::$user)); + + \OC_User::setUserId($loggedInUser); + } } |