/** * scan all the files and folders in a folder * * @param string $path * @param bool $recursive * @param int $reuse * @return int the size of the scanned folder or -1 if the size is unknown at this stage */ public function scanChildren($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1) { if ($reuse === -1) { $reuse = $recursive === self::SCAN_SHALLOW ? self::REUSE_ETAG | self::REUSE_SIZE : 0; } $this->emit('\\OC\\Files\\Cache\\Scanner', 'scanFolder', array($path, $this->storageId)); $size = 0; $childQueue = array(); $existingChildren = array(); if ($this->cache->inCache($path)) { $children = $this->cache->getFolderContents($path); foreach ($children as $child) { $existingChildren[] = $child['name']; } } $newChildren = array(); if ($this->storage->is_dir($path) && ($dh = $this->storage->opendir($path))) { $exceptionOccurred = false; \OC_DB::beginTransaction(); if (is_resource($dh)) { while (($file = readdir($dh)) !== false) { $child = $path ? $path . '/' . $file : $file; if (!Filesystem::isIgnoredDir($file)) { $newChildren[] = $file; try { $data = $this->scanFile($child, $reuse, true); if ($data) { if ($data['size'] === -1) { if ($recursive === self::SCAN_RECURSIVE) { $childQueue[] = $child; } else { $size = -1; } } else { if ($size !== -1) { $size += $data['size']; } } } } catch (\Doctrine\DBAL\DBALException $ex) { // might happen if inserting duplicate while a scanning // process is running in parallel // log and ignore \OC_Log::write('core', 'Exception while scanning file "' . $child . '": ' . $ex->getMessage(), \OC_Log::DEBUG); $exceptionOccurred = true; } } } } $removedChildren = \array_diff($existingChildren, $newChildren); foreach ($removedChildren as $childName) { $child = $path ? $path . '/' . $childName : $childName; $this->cache->remove($child); } \OC_DB::commit(); if ($exceptionOccurred) { // It might happen that the parallel scan process has already // inserted mimetypes but those weren't available yet inside the transaction // To make sure to have the updated mime types in such cases, // we reload them here $this->cache->loadMimetypes(); } foreach ($childQueue as $child) { $childSize = $this->scanChildren($child, self::SCAN_RECURSIVE, $reuse); if ($childSize === -1) { $size = -1; } else { $size += $childSize; } } $this->cache->put($path, array('size' => $size)); } $this->emit('\\OC\\Files\\Cache\\Scanner', 'postScanFolder', array($path, $this->storageId)); return $size; }
/** * Commit the database changes done during a transaction that is in progress */ public static function commit() { return \OC_DB::commit(); }
/** * scan all the files and folders in a folder * * @param string $path * @param bool $recursive * @param int $reuse * @param array $folderData existing cache data for the folder to be scanned * @param bool $lock set to false to disable getting an additional read lock during scanning * @return int the size of the scanned folder or -1 if the size is unknown at this stage */ protected function scanChildren($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $folderData = null, $lock = true) { if ($reuse === -1) { $reuse = $recursive === self::SCAN_SHALLOW ? self::REUSE_ETAG | self::REUSE_SIZE : self::REUSE_ETAG; } $this->emit('\\OC\\Files\\Cache\\Scanner', 'scanFolder', array($path, $this->storageId)); $size = 0; $childQueue = array(); if (is_array($folderData) and isset($folderData['fileid'])) { $folderId = $folderData['fileid']; } else { $folderId = $this->cache->getId($path); } $existingChildren = $this->getExistingChildren($folderId); $newChildren = $this->getNewChildren($path); if ($this->useTransactions) { \OC_DB::beginTransaction(); } $exceptionOccurred = false; foreach ($newChildren as $file) { $child = $path ? $path . '/' . $file : $file; try { $existingData = isset($existingChildren[$file]) ? $existingChildren[$file] : null; $data = $this->scanFile($child, $reuse, $folderId, $existingData, $lock); if ($data) { if ($data['mimetype'] === 'httpd/unix-directory' and $recursive === self::SCAN_RECURSIVE) { $childQueue[$child] = $data; } else { if ($data['size'] === -1) { $size = -1; } else { if ($size !== -1) { $size += $data['size']; } } } } } catch (\Doctrine\DBAL\DBALException $ex) { // might happen if inserting duplicate while a scanning // process is running in parallel // log and ignore \OCP\Util::writeLog('core', 'Exception while scanning file "' . $child . '": ' . $ex->getMessage(), \OCP\Util::DEBUG); $exceptionOccurred = true; } catch (\OCP\Lock\LockedException $e) { if ($this->useTransactions) { \OC_DB::rollback(); } throw $e; } } $removedChildren = \array_diff(array_keys($existingChildren), $newChildren); foreach ($removedChildren as $childName) { $child = $path ? $path . '/' . $childName : $childName; $this->removeFromCache($child); } if ($this->useTransactions) { \OC_DB::commit(); } if ($exceptionOccurred) { // It might happen that the parallel scan process has already // inserted mimetypes but those weren't available yet inside the transaction // To make sure to have the updated mime types in such cases, // we reload them here \OC::$server->getMimeTypeLoader()->reset(); } foreach ($childQueue as $child => $childData) { $childSize = $this->scanChildren($child, self::SCAN_RECURSIVE, $reuse, $childData, $lock); if ($childSize === -1) { $size = -1; } else { if ($size !== -1) { $size += $childSize; } } } if (!is_array($folderData) or !isset($folderData['size']) or $folderData['size'] !== $size) { $this->updateCache($path, array('size' => $size), $folderId); } $this->emit('\\OC\\Files\\Cache\\Scanner', 'postScanFolder', array($path, $this->storageId)); return $size; }
/** * Does a "silent" upgrade, i.e. without an Event-Source as triggered * on User-Login via Ajax. This method is called within the regular * ownCloud upgrade. * * @param string $user a User ID */ public static function doSilentUpgrade($user) { if (!self::needUpgrade($user)) { return; } $legacy = new \OC\Files\Cache\Legacy($user); if ($legacy->hasItems()) { \OC_DB::beginTransaction(); $upgrade = new \OC\Files\Cache\Upgrade($legacy); $upgrade->upgradePath('/' . $user . '/files'); \OC_DB::commit(); } \OC\Files\Cache\Upgrade::upgradeDone($user); }
/** * Move a file or folder in the cache * * @param string $source * @param string $target */ public function move($source, $target) { // normalize source and target $source = $this->normalize($source); $target = $this->normalize($target); $sourceData = $this->get($source); $sourceId = $sourceData['fileid']; $newParentId = $this->getParentId($target); if ($sourceData['mimetype'] === 'httpd/unix-directory') { //find all child entries $sql = 'SELECT `path`, `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path` LIKE ?'; $result = \OC_DB::executeAudited($sql, array($this->getNumericStorageId(), $source . '/%')); $childEntries = $result->fetchAll(); $sourceLength = strlen($source); \OC_DB::beginTransaction(); $query = \OC_DB::prepare('UPDATE `*PREFIX*filecache` SET `path` = ?, `path_hash` = ? WHERE `fileid` = ?'); foreach ($childEntries as $child) { $targetPath = $target . substr($child['path'], $sourceLength); \OC_DB::executeAudited($query, array($targetPath, md5($targetPath), $child['fileid'])); } \OC_DB::commit(); } $sql = 'UPDATE `*PREFIX*filecache` SET `path` = ?, `path_hash` = ?, `name` = ?, `parent` =? WHERE `fileid` = ?'; \OC_DB::executeAudited($sql, array($target, md5($target), basename($target), $newParentId, $sourceId)); }
/** * Commit the database changes done during a transaction that is in progress */ public static function commit() { \OC_DB::commit(); }
OC_Preferences::setValue(OC_User::getUser(), 'media', 'paths', implode(PATH_SEPARATOR, $paths)); } case 'get_collection': $data = array(); $data['artists'] = OC_MEDIA_COLLECTION::getArtists(); $data['albums'] = OC_MEDIA_COLLECTION::getAlbums(); $data['songs'] = OC_MEDIA_COLLECTION::getSongs(); OC_JSON::encodedPrint($data); break; case 'scan': OC_DB::beginTransaction(); set_time_limit(0); //recursive scan can take a while $path = $arguments['path']; echo OC_MEDIA_SCANNER::scanFolder($path); OC_DB::commit(); flush(); break; case 'scanFile': echo OC_MEDIA_SCANNER::scanFile($arguments['path']) ? 'true' : 'false'; break; case 'get_artists': OC_JSON::encodedPrint(OC_MEDIA_COLLECTION::getArtists($arguments['search'])); break; case 'get_albums': OC_JSON::encodedPrint(OC_MEDIA_COLLECTION::getAlbums($arguments['artist'], $arguments['search'])); break; case 'get_songs': OC_JSON::encodedPrint(OC_MEDIA_COLLECTION::getSongs($arguments['artist'], $arguments['album'], $arguments['search'])); break; case 'get_path_info':
/** * 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 = \OC_DB::executeAudited($sql, [$sourceStorageId, $sourcePath . '/%']); $childEntries = $result->fetchAll(); $sourceLength = strlen($sourcePath); \OC_DB::beginTransaction(); $query = \OC_DB::prepare('UPDATE `*PREFIX*filecache` SET `storage` = ?, `path` = ?, `path_hash` = ? WHERE `fileid` = ?'); foreach ($childEntries as $child) { $newTargetPath = $targetPath . substr($child['path'], $sourceLength); \OC_DB::executeAudited($query, [$targetStorageId, $newTargetPath, md5($newTargetPath), $child['fileid']]); } \OC_DB::executeAudited($moveSql, [$targetStorageId, $targetPath, md5($targetPath), basename($targetPath), $newParentId, $sourceId]); \OC_DB::commit(); } else { \OC_DB::executeAudited($moveSql, [$targetStorageId, $targetPath, md5($targetPath), basename($targetPath), $newParentId, $sourceId]); } }