parent
c94fe38d39
commit
954596c251
@ -0,0 +1,189 @@ |
||||
<?php |
||||
/** |
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> |
||||
* This file is licensed under the Affero General Public License version 3 or |
||||
* later. |
||||
* See the COPYING-README file. |
||||
*/ |
||||
|
||||
namespace OC\Files\Cache; |
||||
|
||||
class Cache { |
||||
/** |
||||
* @var array partial data for the cache |
||||
*/ |
||||
private static $partial = array(); |
||||
|
||||
/** |
||||
* get the stored metadata of a file or folder |
||||
* |
||||
* @param \OC\Files\File or int $file |
||||
* @return array |
||||
*/ |
||||
static public function get($file) { |
||||
if ($file instanceof \OC\Files\File) { |
||||
$where = 'WHERE `storage` = ? AND `path_hash` = ?'; |
||||
$params = array($file->getStorageId(), $file->getInternalPath()); |
||||
} else { //file id |
||||
$where = 'WHERE `fileid` = ?'; |
||||
$params = array($file); |
||||
} |
||||
$query = \OC_DB::prepare( |
||||
'SELECT `id`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` |
||||
FROM `*PREFIX*filecache` ' . $where); |
||||
$result=$query->execute($params); |
||||
return $result->fetchRow(); |
||||
} |
||||
|
||||
/** |
||||
* store meta data for a file or folder |
||||
* |
||||
* @param \OC\Files\File $file |
||||
* @param array $data |
||||
* |
||||
* @return int file id |
||||
*/ |
||||
static public function put(\OC\Files\File $file, array $data) { |
||||
if ($id = self::getId($file) > -1) { |
||||
self::update($id, $data); |
||||
return $id; |
||||
} else { |
||||
$key = $file->getStorageId() . '::' . $file->getInternalPath(); |
||||
if (isset(self::$partial[$key])) { //add any saved partial data |
||||
$data = array_merge($data, self::$partial[$key]); |
||||
unset(self::$partial[$key]); |
||||
} |
||||
|
||||
$requiredFields = array('size', 'mtime', 'mimetype'); |
||||
foreach ($requiredFields as $field) { |
||||
if (!isset($data[$field])) { //data not complete save as partial and return |
||||
self::$partial[$key] = $data; |
||||
return -1; |
||||
} |
||||
} |
||||
|
||||
$data['path'] = $file->getInternalPath(); |
||||
$data['parent'] = self::getParentId($file); |
||||
$data['name'] = basename($file->getInternalPath()); |
||||
|
||||
list($queryParts, $params) = self::buildParts($data); |
||||
$queryParts[] = '`storage`'; |
||||
$params[] = $file->getStorageId(); |
||||
$valuesPlaceholder = array_fill(0, count($queryParts), '?'); |
||||
|
||||
$query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ' VALUES(' . implode(', ', $valuesPlaceholder) . ')'); |
||||
$query->execute($params); |
||||
|
||||
return \OC_DB::insertid('*PREFIX*filecache'); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* update the metadata in the cache |
||||
* |
||||
* @param int $id |
||||
* @param array $data |
||||
*/ |
||||
static public function update($id, array $data) { |
||||
list($queryParts, $params) = self::buildParts($data); |
||||
$params[] = $id; |
||||
|
||||
$query = \OC_DB::prepare('UPDATE `*PREFIX*filecache` SET ' . implode(' = ?, ', $queryParts) . '=? WHERE fileid = ?'); |
||||
$query->execute($params); |
||||
} |
||||
|
||||
/** |
||||
* extract query parts and params array from data array |
||||
* |
||||
* @param array $data |
||||
* @return array |
||||
*/ |
||||
private static function buildParts(array $data) { |
||||
$fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime'); |
||||
|
||||
$params = array(); |
||||
$queryParts = array(); |
||||
foreach ($data as $name => $value) { |
||||
if (array_search($name, $fields) !== false) { |
||||
$params[] = $value; |
||||
$queryParts[] = '`' . $name . '`'; |
||||
if ($name === 'path') { |
||||
$params[] = md5($value); |
||||
$queryParts[] = '`path_hash`'; |
||||
} elseif ($name === 'mimetype') { |
||||
$params[] = substr($value, 0, strpos($value, '/')); |
||||
$queryParts[] = '`mimepart`'; |
||||
} |
||||
} |
||||
} |
||||
return array($queryParts, $params); |
||||
} |
||||
|
||||
/** |
||||
* get the file id for a file |
||||
* |
||||
* @param \OC\Files\File $file |
||||
* @return int |
||||
*/ |
||||
static public function getId(\OC\Files\File $file) { |
||||
$storageId = $file->getStorageId(); |
||||
$pathHash = md5($file->getInternalPath()); |
||||
|
||||
$query = \OC_DB::prepare('SELECT id FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); |
||||
$result = $query->execute(array($storageId, $pathHash)); |
||||
|
||||
if ($row = $result->fetchRow()) { |
||||
return $row['id']; |
||||
} else { |
||||
return -1; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* get the id of the parent folder of a file |
||||
* |
||||
* @param \OC\Files\File $file |
||||
* return int |
||||
*/ |
||||
static public function getParentId(\OC\Files\File $file) { |
||||
$path = $file->getInternalPath(); |
||||
if ($path === '/' or $path === '') { |
||||
return -1; |
||||
} else { |
||||
return self::getId(new \OC\Files\File($file->getStorage(), dirname($path))); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* check if a file is available in the cache |
||||
* |
||||
* @param \OC\Files\File $file |
||||
* @return bool |
||||
*/ |
||||
static public function inCache(\OC\Files\File $file) { |
||||
return self::getId($file) != -1; |
||||
} |
||||
|
||||
/** |
||||
* remove a file or folder from the cache |
||||
* |
||||
* @param \OC\Files\File $file |
||||
*/ |
||||
public function remove(\OC\Files\File $file) { |
||||
$storageId = $file->getStorageId(); |
||||
$pathHash = md5($file->getInternalPath()); |
||||
$query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); |
||||
$query->execute(array($storageId, $pathHash)); |
||||
} |
||||
|
||||
/** |
||||
* remove all entries for files that are stored on $storage form the cache |
||||
* |
||||
* @param \OC\Files\Storage\Storage $storage |
||||
*/ |
||||
public function removeStorage(\OC\Files\Storage\Storage $storage) { |
||||
$storageId = $storage->getId(); |
||||
$query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE storage=?'); |
||||
$query->execute(array($storageId)); |
||||
} |
||||
} |
||||
@ -0,0 +1,78 @@ |
||||
<?php |
||||
/** |
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> |
||||
* This file is licensed under the Affero General Public License version 3 or |
||||
* later. |
||||
* See the COPYING-README file. |
||||
*/ |
||||
|
||||
namespace OC\Files\Cache; |
||||
|
||||
class Scanner { |
||||
const SCAN_RECURSIVE = true; |
||||
const SCAN_SHALLOW = false; |
||||
|
||||
/** |
||||
* get all the metadata of a file or folder |
||||
* * |
||||
* @param \OC\Files\File $file |
||||
* @return array with metadata of the file |
||||
*/ |
||||
public static function getData(\OC\Files\File $file) { |
||||
$data = array(); |
||||
$storage = $file->getStorage(); |
||||
$path = $file->getInternalPath(); |
||||
if (!$storage->isReadable($path)) return null; //cant read, nothing we can do |
||||
clearstatcache(); |
||||
$data['mimetype'] = $storage->getMimeType($path); |
||||
$data['mtime'] = $storage->filemtime($path); |
||||
if ($data['mimetype'] == 'httpd/unix-directory') { |
||||
$data['size'] = -1; //unknown |
||||
$data['permissions'] = $storage->getPermissions($path . '/'); |
||||
} else { |
||||
$data['size'] = $storage->filesize($path); |
||||
$data['permissions'] = $storage->getPermissions($path); |
||||
} |
||||
return $data; |
||||
} |
||||
|
||||
/** |
||||
* scan a single file and store it in the cache |
||||
* |
||||
* @param \OC\Files\File $file |
||||
* @return array with metadata of the scanned file |
||||
*/ |
||||
public static function scanFile(\OC\Files\File $file) { |
||||
$data = self::getData($file); |
||||
Cache::put($file, $data); |
||||
return $data; |
||||
} |
||||
|
||||
/** |
||||
* scan all the files in a folder and store them in the cache |
||||
* |
||||
* @param \OC\Files\File $folder |
||||
* @param SCAN_RECURSIVE/SCAN_SHALLOW $recursive |
||||
* @return int the size of the scanned folder or -1 if the size is unknown at this stage |
||||
*/ |
||||
public static function scan(\OC\Files\File $folder, $recursive) { |
||||
$size = 0; |
||||
$storage = $folder->getStorage(); |
||||
$path = $folder->getInternalPath(); |
||||
if ($dh = $storage->opendir($path)) { |
||||
while ($file = readdir($dh)) { |
||||
if ($file !== '.' and $file !== '..') { |
||||
$child = new \OC\Files\File($storage, $path . '/' . $file); |
||||
$data = self::scanFile($child); |
||||
if ($recursive === self::SCAN_RECURSIVE and $data['mimetype'] === 'httpd/unix-directory') { |
||||
$data['size'] = self::scan($child, self::SCAN_RECURSIVE); |
||||
} |
||||
if ($data['size'] >= 0 and $size >= 0) { |
||||
$size += $data['size']; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return $size; |
||||
} |
||||
} |
||||
@ -0,0 +1,61 @@ |
||||
<?php |
||||
/** |
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> |
||||
* This file is licensed under the Affero General Public License version 3 or |
||||
* later. |
||||
* See the COPYING-README file. |
||||
*/ |
||||
|
||||
namespace OC\Files; |
||||
|
||||
/** |
||||
* representation of the location a file or folder is stored |
||||
*/ |
||||
|
||||
class File{ |
||||
/** |
||||
* @var Storage\Storage $storage |
||||
*/ |
||||
private $storage; |
||||
/** |
||||
* @var string internalPath |
||||
*/ |
||||
private $internalPath; |
||||
|
||||
public function __construct(Storage\Storage $storage, $internalPath){ |
||||
$this->storage = $storage; |
||||
$this->internalPath = $internalPath; |
||||
} |
||||
|
||||
public static function resolve($fullPath){ |
||||
$storage = null; |
||||
$internalPath = ''; |
||||
list($storage, $internalPath) = \OC_Filesystem::resolvePath($fullPath); |
||||
return new File($storage, $internalPath); |
||||
} |
||||
|
||||
/** |
||||
* get the internal path of the file inside the filestorage |
||||
* @return string |
||||
*/ |
||||
public function getInternalPath(){ |
||||
return $this->internalPath; |
||||
} |
||||
|
||||
/** |
||||
* get the storage the file is stored in |
||||
* @return \OC\Files\Storage\Storage |
||||
*/ |
||||
public function getStorage(){ |
||||
return $this->storage; |
||||
} |
||||
|
||||
/** |
||||
* get the id of the storage the file is stored in |
||||
* @return string |
||||
*/ |
||||
public function getStorageId(){ |
||||
return $this->storage->getId(); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue