Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/dav/lib/Connector/Sabre/File.php13
-rw-r--r--apps/dav/lib/Connector/Sabre/FilesPlugin.php18
-rw-r--r--apps/dav/lib/Connector/Sabre/Node.php8
-rw-r--r--apps/files_trashbin/lib/Trash/TrashItem.php8
-rw-r--r--core/Migrations/Version17000Date20190514105811.php2
-rw-r--r--lib/composer/composer/autoload_classmap.php1
-rw-r--r--lib/composer/composer/autoload_static.php1
-rw-r--r--lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php5
-rw-r--r--lib/private/DB/QueryBuilder/QueryBuilder.php62
-rw-r--r--lib/private/Files/Cache/Cache.php432
-rw-r--r--lib/private/Files/Cache/CacheEntry.php12
-rw-r--r--lib/private/Files/Cache/CacheQueryBuilder.php92
-rw-r--r--lib/private/Files/Cache/MoveFromCacheTrait.php5
-rw-r--r--lib/private/Files/FileInfo.php8
-rw-r--r--lib/private/Files/Node/LazyRoot.php14
-rw-r--r--lib/private/Files/Node/Node.php8
-rw-r--r--lib/public/DB/QueryBuilder/IFunctionBuilder.php2
-rw-r--r--lib/public/DB/QueryBuilder/IQueryBuilder.php62
-rw-r--r--lib/public/Files/Cache/ICacheEntry.php24
-rw-r--r--lib/public/Files/FileInfo.php26
-rw-r--r--tests/lib/Files/Cache/CacheTest.php70
-rw-r--r--tests/lib/Files/ViewTest.php449
-rw-r--r--tests/lib/HelperStorageTest.php1
23 files changed, 869 insertions, 454 deletions
diff --git a/apps/dav/lib/Connector/Sabre/File.php b/apps/dav/lib/Connector/Sabre/File.php
index 2d019b46b6a..3ce305d75f3 100644
--- a/apps/dav/lib/Connector/Sabre/File.php
+++ b/apps/dav/lib/Connector/Sabre/File.php
@@ -303,6 +303,19 @@ class File extends Node implements IFile {
}
}
+ $fileInfoUpdate = [
+ 'upload_time' => time()
+ ];
+
+ // allow sync clients to send the creation time along in a header
+ if (isset($this->request->server['HTTP_X_OC_CTIME'])) {
+ $ctime = $this->sanitizeMtime($this->request->server['HTTP_X_OC_CTIME']);
+ $fileInfoUpdate['creation_time'] = $ctime;
+ $this->header('X-OC-CTime: accepted');
+ }
+
+ $this->fileView->putFileInfo($this->path, $fileInfoUpdate);
+
if ($view) {
$this->emitPostHooks($exists);
}
diff --git a/apps/dav/lib/Connector/Sabre/FilesPlugin.php b/apps/dav/lib/Connector/Sabre/FilesPlugin.php
index 99317f2bc1c..b2a0e9a31b4 100644
--- a/apps/dav/lib/Connector/Sabre/FilesPlugin.php
+++ b/apps/dav/lib/Connector/Sabre/FilesPlugin.php
@@ -70,6 +70,9 @@ class FilesPlugin extends ServerPlugin {
const HAS_PREVIEW_PROPERTYNAME = '{http://nextcloud.org/ns}has-preview';
const MOUNT_TYPE_PROPERTYNAME = '{http://nextcloud.org/ns}mount-type';
const IS_ENCRYPTED_PROPERTYNAME = '{http://nextcloud.org/ns}is-encrypted';
+ const METADATA_ETAG_PROPERTYNAME = '{http://nextcloud.org/ns}metadata_etag';
+ const UPLOAD_TIME_PROPERTYNAME = '{http://nextcloud.org/ns}upload_time';
+ const CREATION_TIME_PROPERTYNAME = '{http://nextcloud.org/ns}creation_time';
const SHARE_NOTE = '{http://nextcloud.org/ns}note';
/**
@@ -400,6 +403,14 @@ class FilesPlugin extends ServerPlugin {
return new ChecksumList($checksum);
});
+ $propFind->handle(self::CREATION_TIME_PROPERTYNAME, function() use ($node) {
+ return $node->getFileInfo()->getCreationTime();
+ });
+
+ $propFind->handle(self::UPLOAD_TIME_PROPERTYNAME, function() use ($node) {
+ return $node->getFileInfo()->getUploadTime();
+ });
+
}
if ($node instanceof \OCA\DAV\Connector\Sabre\Directory) {
@@ -470,6 +481,13 @@ class FilesPlugin extends ServerPlugin {
}
return false;
});
+ $propPatch->handle(self::CREATION_TIME_PROPERTYNAME, function($time) use ($node) {
+ if (empty($time)) {
+ return false;
+ }
+ $node->setCreationTime((int) $time);
+ return true;
+ });
}
/**
diff --git a/apps/dav/lib/Connector/Sabre/Node.php b/apps/dav/lib/Connector/Sabre/Node.php
index f0917fe11b2..2a3e8145f6f 100644
--- a/apps/dav/lib/Connector/Sabre/Node.php
+++ b/apps/dav/lib/Connector/Sabre/Node.php
@@ -201,6 +201,14 @@ abstract class Node implements \Sabre\DAV\INode {
return $this->fileView->putFileInfo($this->path, array('etag' => $etag));
}
+ public function setCreationTime(int $time) {
+ return $this->fileView->putFileInfo($this->path, array('creation_time' => $time));
+ }
+
+ public function setUploadTime(int $time) {
+ return $this->fileView->putFileInfo($this->path, array('upload_time' => $time));
+ }
+
/**
* Returns the size of the node, in bytes
*
diff --git a/apps/files_trashbin/lib/Trash/TrashItem.php b/apps/files_trashbin/lib/Trash/TrashItem.php
index 0112b6dbc8e..71830d8b91e 100644
--- a/apps/files_trashbin/lib/Trash/TrashItem.php
+++ b/apps/files_trashbin/lib/Trash/TrashItem.php
@@ -177,4 +177,12 @@ class TrashItem implements ITrashItem {
public function getTitle(): string {
return $this->getOriginalLocation();
}
+
+ public function getCreationTime(): int {
+ return $this->fileInfo->getCreationTime();
+ }
+
+ public function getUploadTime(): int {
+ return $this->fileInfo->getUploadTime();
+ }
}
diff --git a/core/Migrations/Version17000Date20190514105811.php b/core/Migrations/Version17000Date20190514105811.php
index 7f8084f9832..1cf4c9f5a37 100644
--- a/core/Migrations/Version17000Date20190514105811.php
+++ b/core/Migrations/Version17000Date20190514105811.php
@@ -44,7 +44,7 @@ class Version17000Date20190514105811 extends SimpleMigrationStep {
$schema = $schemaClosure();
if(!$schema->hasTable('filecache_extended')) {
$table = $schema->createTable('filecache_extended');
- $table->addColumn('fileid', Type::INTEGER, [
+ $table->addColumn('fileid', Type::BIGINT, [
'notnull' => true,
'length' => 4,
'unsigned' => true,
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 915efa90609..cf28f634cab 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -866,6 +866,7 @@ return array(
'OC\\Files\\Cache\\AbstractCacheEvent' => $baseDir . '/lib/private/Files/Cache/AbstractCacheEvent.php',
'OC\\Files\\Cache\\Cache' => $baseDir . '/lib/private/Files/Cache/Cache.php',
'OC\\Files\\Cache\\CacheEntry' => $baseDir . '/lib/private/Files/Cache/CacheEntry.php',
+ 'OC\\Files\\Cache\\CacheQueryBuilder' => $baseDir . '/lib/private/Files/Cache/CacheQueryBuilder.php',
'OC\\Files\\Cache\\FailedCache' => $baseDir . '/lib/private/Files/Cache/FailedCache.php',
'OC\\Files\\Cache\\HomeCache' => $baseDir . '/lib/private/Files/Cache/HomeCache.php',
'OC\\Files\\Cache\\HomePropagator' => $baseDir . '/lib/private/Files/Cache/HomePropagator.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index 22a070774f8..aa12c20ac13 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -895,6 +895,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Files\\Cache\\AbstractCacheEvent' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/AbstractCacheEvent.php',
'OC\\Files\\Cache\\Cache' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/Cache.php',
'OC\\Files\\Cache\\CacheEntry' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/CacheEntry.php',
+ 'OC\\Files\\Cache\\CacheQueryBuilder' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/CacheQueryBuilder.php',
'OC\\Files\\Cache\\FailedCache' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/FailedCache.php',
'OC\\Files\\Cache\\HomeCache' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/HomeCache.php',
'OC\\Files\\Cache\\HomePropagator' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/HomePropagator.php',
diff --git a/lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php b/lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php
index 3b67661c8b0..46bb536dfd2 100644
--- a/lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php
+++ b/lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php
@@ -72,9 +72,10 @@ class FunctionBuilder implements IFunctionBuilder {
return new QueryFunction($this->helper->quoteColumnName($x) . ' - ' . $this->helper->quoteColumnName($y));
}
- public function count($count, $alias = '') {
+ public function count($count = '', $alias = '') {
$alias = $alias ? (' AS ' . $this->helper->quoteColumnName($alias)) : '';
- return new QueryFunction('COUNT(' . $this->helper->quoteColumnName($count) . ')' . $alias);
+ $quotedName = $count === '' ? '*' : $this->helper->quoteColumnName($count);
+ return new QueryFunction('COUNT(' . $quotedName . ')' . $alias);
}
public function max($field) {
diff --git a/lib/private/DB/QueryBuilder/QueryBuilder.php b/lib/private/DB/QueryBuilder/QueryBuilder.php
index 25d59fb7d7d..bff38c0c8d6 100644
--- a/lib/private/DB/QueryBuilder/QueryBuilder.php
+++ b/lib/private/DB/QueryBuilder/QueryBuilder.php
@@ -245,7 +245,7 @@ class QueryBuilder implements IQueryBuilder {
* @param mixed $value The parameter value.
* @param string|null|int $type One of the IQueryBuilder::PARAM_* constants.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function setParameter($key, $value, $type = null) {
$this->queryBuilder->setParameter($key, $value, $type);
@@ -270,7 +270,7 @@ class QueryBuilder implements IQueryBuilder {
* @param array $params The query parameters to set.
* @param array $types The query parameters types to set.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function setParameters(array $params, array $types = array()) {
$this->queryBuilder->setParameters($params, $types);
@@ -323,7 +323,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param integer $firstResult The first result to return.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function setFirstResult($firstResult) {
$this->queryBuilder->setFirstResult($firstResult);
@@ -350,7 +350,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param integer $maxResults The maximum number of results to retrieve.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function setMaxResults($maxResults) {
$this->queryBuilder->setMaxResults($maxResults);
@@ -381,7 +381,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed ...$selects The selection expressions.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * '@return $this This QueryBuilder instance.
*/
public function select(...$selects) {
if (count($selects) === 1 && is_array($selects[0])) {
@@ -408,7 +408,7 @@ class QueryBuilder implements IQueryBuilder {
* @param mixed $select The selection expressions.
* @param string $alias The column alias used in the constructed query.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function selectAlias($select, $alias) {
@@ -430,7 +430,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed $select The selection expressions.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function selectDistinct($select) {
@@ -454,7 +454,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed ...$selects The selection expression.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function addSelect(...$selects) {
if (count($selects) === 1 && is_array($selects[0])) {
@@ -482,7 +482,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $delete The table whose rows are subject to the deletion.
* @param string $alias The table alias used in the constructed query.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function delete($delete = null, $alias = null) {
$this->queryBuilder->delete(
@@ -507,7 +507,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $update The table whose rows are subject to the update.
* @param string $alias The table alias used in the constructed query.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function update($update = null, $alias = null) {
$this->queryBuilder->update(
@@ -535,7 +535,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param string $insert The table into which the rows should be inserted.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function insert($insert = null) {
$this->queryBuilder->insert(
@@ -560,7 +560,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $from The table.
* @param string|null $alias The alias of the table.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function from($from, $alias = null) {
$this->queryBuilder->from(
@@ -586,7 +586,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $alias The alias of the join table.
* @param string $condition The condition for the join.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function join($fromAlias, $join, $alias, $condition = null) {
$this->queryBuilder->join(
@@ -614,7 +614,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $alias The alias of the join table.
* @param string $condition The condition for the join.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function innerJoin($fromAlias, $join, $alias, $condition = null) {
$this->queryBuilder->innerJoin(
@@ -642,7 +642,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $alias The alias of the join table.
* @param string $condition The condition for the join.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function leftJoin($fromAlias, $join, $alias, $condition = null) {
$this->queryBuilder->leftJoin(
@@ -670,7 +670,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $alias The alias of the join table.
* @param string $condition The condition for the join.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function rightJoin($fromAlias, $join, $alias, $condition = null) {
$this->queryBuilder->rightJoin(
@@ -696,7 +696,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $key The column to set.
* @param string $value The value, expression, placeholder, etc.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function set($key, $value) {
$this->queryBuilder->set(
@@ -731,7 +731,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed ...$predicates The restriction predicates.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function where(...$predicates) {
call_user_func_array(
@@ -756,7 +756,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed ...$where The query restrictions.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*
* @see where()
*/
@@ -783,7 +783,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed ...$where The WHERE statement.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*
* @see where()
*/
@@ -809,7 +809,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed ...$groupBys The grouping expression.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function groupBy(...$groupBys) {
if (count($groupBys) === 1 && is_array($groupBys[0])) {
@@ -837,7 +837,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed ...$groupBy The grouping expression.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function addGroupBy(...$groupBys) {
if (count($groupBys) === 1 && is_array($groupBys[0])) {
@@ -869,7 +869,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $column The column into which the value should be inserted.
* @param string $value The value that should be inserted into the column.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function setValue($column, $value) {
$this->queryBuilder->setValue(
@@ -897,7 +897,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param array $values The values to specify for the insert query indexed by column names.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function values(array $values) {
$quotedValues = [];
@@ -916,7 +916,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed ...$having The restriction over the groups.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function having(...$having) {
call_user_func_array(
@@ -933,7 +933,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed ...$having The restriction to append.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function andHaving(...$having) {
call_user_func_array(
@@ -950,7 +950,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed ...$having The restriction to add.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function orHaving(...$having) {
call_user_func_array(
@@ -968,7 +968,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $sort The ordering expression.
* @param string $order The ordering direction.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function orderBy($sort, $order = null) {
$this->queryBuilder->orderBy(
@@ -985,7 +985,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $sort The ordering expression.
* @param string $order The ordering direction.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function addOrderBy($sort, $order = null) {
$this->queryBuilder->addOrderBy(
@@ -1021,7 +1021,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param array|null $queryPartNames
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function resetQueryParts($queryPartNames = null) {
$this->queryBuilder->resetQueryParts($queryPartNames);
@@ -1034,7 +1034,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param string $queryPartName
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function resetQueryPart($queryPartName) {
$this->queryBuilder->resetQueryPart($queryPartName);
diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php
index f6139d8abed..f1d2c64e8fd 100644
--- a/lib/private/Files/Cache/Cache.php
+++ b/lib/private/Files/Cache/Cache.php
@@ -45,6 +45,7 @@ use OCP\Files\Cache\CacheInsertEvent;
use OCP\Files\Cache\CacheUpdateEvent;
use OCP\Files\Cache\ICache;
use OCP\Files\Cache\ICacheEntry;
+use OCP\Files\FileInfo;
use \OCP\Files\IMimeTypeLoader;
use OCP\Files\Search\ISearchQuery;
use OCP\Files\Storage\IStorage;
@@ -68,7 +69,7 @@ class Cache implements ICache {
/**
* @var array partial data for the cache
*/
- protected $partial = array();
+ protected $partial = [];
/**
* @var string
@@ -112,6 +113,15 @@ class Cache implements ICache {
$this->querySearchHelper = new QuerySearchHelper($this->mimetypeLoader);
}
+ private function getQueryBuilder() {
+ return new CacheQueryBuilder(
+ $this->connection,
+ \OC::$server->getSystemConfig(),
+ \OC::$server->getLogger(),
+ $this
+ );
+ }
+
/**
* Get the numeric storage id for this cache's storage
*
@@ -128,34 +138,24 @@ class Cache implements ICache {
* @return ICacheEntry|false the cache entry as array of false if the file is not found in the cache
*/
public function get($file) {
+ $query = $this->getQueryBuilder();
+ $query->selectFileCache();
+
if (is_string($file) or $file == '') {
// normalize file
$file = $this->normalize($file);
- $where = 'WHERE `storage` = ? AND `path_hash` = ?';
- $params = array($this->getNumericStorageId(), md5($file));
+ $query->whereStorageId()
+ ->wherePath($file);
} else { //file id
- $where = 'WHERE `fileid` = ?';
- $params = array($file);
+ $query->whereFileId($file);
}
- $sql = 'SELECT `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`,
- `storage_mtime`, `encrypted`, `etag`, `permissions`, `checksum`
- FROM `*PREFIX*filecache` ' . $where;
- $result = $this->connection->executeQuery($sql, $params);
- $data = $result->fetch();
- //FIXME hide this HACK in the next database layer, or just use doctrine and get rid of MDB2 and PDO
- //PDO returns false, MDB2 returns null, oracle always uses MDB2, so convert null to false
- if ($data === null) {
- $data = false;
- }
+ $data = $query->execute()->fetch();
//merge partial data
- if (!$data and is_string($file)) {
- if (isset($this->partial[$file])) {
- $data = $this->partial[$file];
- }
- return $data;
+ if (!$data and is_string($file) and isset($this->partial[$file])) {
+ return $this->partial[$file];
} else if (!$data) {
return $data;
} else {
@@ -187,6 +187,12 @@ class Cache implements ICache {
$data['storage_mtime'] = $data['mtime'];
}
$data['permissions'] = (int)$data['permissions'];
+ if (isset($data['creation_time'])) {
+ $data['creation_time'] = (int) $data['creation_time'];
+ }
+ if (isset($data['upload_time'])) {
+ $data['upload_time'] = (int) $data['upload_time'];
+ }
return new CacheEntry($data);
}
@@ -209,11 +215,12 @@ class Cache implements ICache {
*/
public function getFolderContentsById($fileId) {
if ($fileId > -1) {
- $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`,
- `storage_mtime`, `encrypted`, `etag`, `permissions`, `checksum`
- FROM `*PREFIX*filecache` WHERE `parent` = ? ORDER BY `name` ASC';
- $result = $this->connection->executeQuery($sql, [$fileId]);
- $files = $result->fetchAll();
+ $query = $this->getQueryBuilder();
+ $query->selectFileCache()
+ ->whereParent($fileId)
+ ->orderBy('name', 'ASC');
+
+ $files = $query->execute()->fetchAll();
return array_map(function (array $data) {
return self::cacheEntryFromData($data, $this->mimetypeLoader);
}, $files);
@@ -259,7 +266,7 @@ class Cache implements ICache {
unset($this->partial[$file]);
}
- $requiredFields = array('size', 'mtime', 'mimetype');
+ $requiredFields = ['size', 'mtime', 'mimetype'];
foreach ($requiredFields as $field) {
if (!isset($data[$field])) { //data not complete save as partial and return
$this->partial[$file] = $data;
@@ -271,14 +278,8 @@ class Cache implements ICache {
$data['parent'] = $this->getParentId($file);
$data['name'] = basename($file);
- list($queryParts, $params) = $this->buildParts($data);
- $queryParts[] = '`storage`';
- $params[] = $this->getNumericStorageId();
-
- $queryParts = array_map(function ($item) {
- return trim($item, "`");
- }, $queryParts);
- $values = array_combine($queryParts, $params);
+ [$values, $extensionValues] = $this->normalizeData($data);
+ $values['storage'] = $this->getNumericStorageId();
try {
$builder = $this->connection->getQueryBuilder();
@@ -289,7 +290,19 @@ class Cache implements ICache {
}
if ($builder->execute()) {
- $fileId = (int)$this->connection->lastInsertId('*PREFIX*filecache');
+ $fileId = $builder->getLastInsertId();
+
+ if (count($extensionValues)) {
+ $query = $this->getQueryBuilder();
+ $query->insert('filecache_extended');
+
+ $query->setValue('fileid', $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT));
+ foreach ($extensionValues as $column => $value) {
+ $query->setValue($column, $query->createNamedParameter($value));
+ }
+ $query->execute();
+ }
+
$this->eventDispatcher->dispatch(CacheInsertEvent::class, new CacheInsertEvent($this->storage, $file, $fileId));
return $fileId;
}
@@ -324,20 +337,56 @@ class Cache implements ICache {
$data['name'] = $this->normalize($data['name']);
}
- list($queryParts, $params) = $this->buildParts($data);
- // duplicate $params because we need the parts twice in the SQL statement
- // once for the SET part, once in the WHERE clause
- $params = array_merge($params, $params);
- $params[] = $id;
+ [$values, $extensionValues] = $this->normalizeData($data);
- // don't update if the data we try to set is the same as the one in the record
- // some databases (Postgres) don't like superfluous updates
- $sql = 'UPDATE `*PREFIX*filecache` SET ' . implode(' = ?, ', $queryParts) . '=? ' .
- 'WHERE (' .
- implode(' <> ? OR ', $queryParts) . ' <> ? OR ' .
- implode(' IS NULL OR ', $queryParts) . ' IS NULL' .
- ') AND `fileid` = ? ';
- $this->connection->executeQuery($sql, $params);
+ if (count($values)) {
+ $query = $this->getQueryBuilder();
+
+ $query->update('filecache')
+ ->whereFileId($id)
+ ->andWhere($query->expr()->orX(...array_map(function ($key, $value) use ($query) {
+ return $query->expr()->orX(
+ $query->expr()->neq($key, $query->createNamedParameter($value)),
+ $query->expr()->isNull($key)
+ );
+ }, array_keys($values), array_values($values))));
+
+ foreach ($values as $key => $value) {
+ $query->set($key, $query->createNamedParameter($value));
+ }
+
+ $query->execute();
+ }
+
+ if (count($extensionValues)) {
+ try {
+ $query = $this->getQueryBuilder();
+ $query->insert('filecache_extended');
+
+ $query->setValue('fileid', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT));
+ foreach ($extensionValues as $column => $value) {
+ $query->setValue($column, $query->createNamedParameter($value));
+ }
+
+ $query->execute();
+ } catch (UniqueConstraintViolationException $e) {
+ $query = $this->getQueryBuilder();
+ $query->update('filecache_extended')
+ ->whereFileId($id)
+ ->andWhere($query->expr()->orX(...array_map(function ($key, $value) use ($query) {
+ return $query->expr()->orX(
+ $query->expr()->neq($key, $query->createNamedParameter($value)),
+ $query->expr()->isNull($key)
+ );
+ }, array_keys($extensionValues), array_values($extensionValues))));
+
+ foreach ($extensionValues as $key => $value) {
+ $query->set($key, $query->createNamedParameter($value));
+ }
+
+ $query->execute();
+ }
+ }
$path = $this->getPathById($id);
// path can still be null if the file doesn't exist
@@ -350,14 +399,13 @@ class Cache implements ICache {
* extract query parts and params array from data array
*
* @param array $data
- * @return array [$queryParts, $params]
- * $queryParts: string[], the (escaped) column names to be set in the query
- * $params: mixed[], the new values for the columns, to be passed as params to the query
+ * @return array
*/
- protected function buildParts(array $data) {
- $fields = array(
+ protected function normalizeData(array $data): array {
+ $fields = [
'path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'storage_mtime', 'encrypted',
- 'etag', 'permissions', 'checksum', 'storage');
+ 'etag', 'permissions', 'checksum', 'storage'];
+ $extensionFields = ['metadata_etag', 'creation_time', 'upload_time'];
$doNotCopyStorageMTime = false;
if (array_key_exists('mtime', $data) && $data['mtime'] === null) {
@@ -366,23 +414,20 @@ class Cache implements ICache {
$doNotCopyStorageMTime = true;
}
- $params = array();
- $queryParts = array();
+ $params = [];
+ $extensionParams = [];
foreach ($data as $name => $value) {
if (array_search($name, $fields) !== false) {
if ($name === 'path') {
- $params[] = md5($value);
- $queryParts[] = '`path_hash`';
- } elseif ($name === 'mimetype') {
- $params[] = $this->mimetypeLoader->getId(substr($value, 0, strpos($value, '/')));
- $queryParts[] = '`mimepart`';
+ $params['path_hash'] = md5($value);
+ } else if ($name === 'mimetype') {
+ $params['mimepart'] = $this->mimetypeLoader->getId(substr($value, 0, strpos($value, '/')));
$value = $this->mimetypeLoader->getId($value);
- } elseif ($name === 'storage_mtime') {
+ } else if ($name === 'storage_mtime') {
if (!$doNotCopyStorageMTime && !isset($data['mtime'])) {
- $params[] = $value;
- $queryParts[] = '`mtime`';
+ $params['mtime'] = $value;
}
- } elseif ($name === 'encrypted') {
+ } else if ($name === 'encrypted') {
if (isset($data['encryptedVersion'])) {
$value = $data['encryptedVersion'];
} else {
@@ -390,11 +435,13 @@ class Cache implements ICache {
$value = $value ? 1 : 0;
}
}
- $params[] = $value;
- $queryParts[] = '`' . $name . '`';
+ $params[$name] = $value;
+ }
+ if (array_search($name, $extensionFields) !== false) {
+ $extensionParams[$name] = $value;
}
}
- return array($queryParts, $params);
+ return [$params, array_filter($extensionParams)];
}
/**
@@ -411,15 +458,14 @@ class Cache implements ICache {
// normalize file
$file = $this->normalize($file);
- $pathHash = md5($file);
+ $query = $this->getQueryBuilder();
+ $query->select('fileid')
+ ->from('filecache')
+ ->whereStorageId()
+ ->wherePath($file);
- $sql = 'SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?';
- $result = $this->connection->executeQuery($sql, array($this->getNumericStorageId(), $pathHash));
- if ($row = $result->fetch()) {
- return (int)$row['fileid'];
- } else {
- return -1;
- }
+ $id = $query->execute()->fetchColumn();
+ return $id === false ? -1 : (int)$id;
}
/**
@@ -464,39 +510,64 @@ class Cache implements ICache {
*/
public function remove($file) {
$entry = $this->get($file);
- $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `fileid` = ?';
- $this->connection->executeQuery($sql, array($entry['fileid']));
- if ($entry['mimetype'] === 'httpd/unix-directory') {
- $this->removeChildren($entry);
+
+ if ($entry) {
+ $query = $this->getQueryBuilder();
+ $query->delete('filecache')
+ ->whereFileId($entry->getId());
+ $query->execute();
+
+ $query = $this->getQueryBuilder();
+ $query->delete('filecache_extended')
+ ->whereFileId($entry->getId());
+ $query->execute();
+
+ if ($entry->getMimeType() == FileInfo::MIMETYPE_FOLDER) {
+ $this->removeChildren($entry);
+ }
}
}
/**
* Get all sub folders of a folder
*
- * @param array $entry the cache entry of the folder to get the subfolders for
- * @return array[] the cache entries for the subfolders
+ * @param ICacheEntry $entry the cache entry of the folder to get the subfolders for
+ * @return ICacheEntry[] the cache entries for the subfolders
*/
- private function getSubFolders($entry) {
- $children = $this->getFolderContentsById($entry['fileid']);
+ private function getSubFolders(ICacheEntry $entry) {
+ $children = $this->getFolderContentsById($entry->getId());
return array_filter($children, function ($child) {
- return $child['mimetype'] === 'httpd/unix-directory';
+ return $child->getMimeType() == FileInfo::MIMETYPE_FOLDER;
});
}
/**
* Recursively remove all children of a folder
*
- * @param array $entry the cache entry of the folder to remove the children of
+ * @param ICacheEntry $entry the cache entry of the folder to remove the children of
* @throws \OC\DatabaseException
*/
- private function removeChildren($entry) {
- $subFolders = $this->getSubFolders($entry);
- foreach ($subFolders as $folder) {
+ private function removeChildren(ICacheEntry $entry) {
+ $children = $this->getFolderContentsById($entry->getId());
+ $childIds = array_map(function(ICacheEntry $cacheEntry) {
+ return $cacheEntry->getId();
+ }, $children);
+ $childFolders = array_filter($children, function ($child) {
+ return $child->getMimeType() == FileInfo::MIMETYPE_FOLDER;
+ });
+ foreach ($childFolders as $folder) {
$this->removeChildren($folder);
}
- $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `parent` = ?';
- $this->connection->executeQuery($sql, array($entry['fileid']));
+
+ $query = $this->getQueryBuilder();
+ $query->delete('filecache')
+ ->whereParent($entry->getId());
+ $query->execute();
+
+ $query = $this->getQueryBuilder();
+ $query->delete('filecache_extended')
+ ->where($query->expr()->in('fileid', $query->createNamedParameter($childIds, IQueryBuilder::PARAM_INT_ARRAY)));
+ $query->execute();
}
/**
@@ -575,8 +646,16 @@ class Cache implements ICache {
}
}
- $sql = 'UPDATE `*PREFIX*filecache` SET `storage` = ?, `path` = ?, `path_hash` = ?, `name` = ?, `parent` = ? WHERE `fileid` = ?';
- $this->connection->executeQuery($sql, array($targetStorageId, $targetPath, md5($targetPath), basename($targetPath), $newParentId, $sourceId));
+ $query = $this->getQueryBuilder();
+ $query->update('filecache')
+ ->set('storage', $query->createNamedParameter($targetStorageId))
+ ->set('path', $query->createNamedParameter($targetPath))
+ ->set('path_hash', $query->createNamedParameter(md5($targetPath)))
+ ->set('name', $query->createNamedParameter(basename($targetPath)))
+ ->set('parent', $query->createNamedParameter($newParentId, IQueryBuilder::PARAM_INT))
+ ->whereFileId($sourceId);
+ $query->execute();
+
$this->connection->commit();
} else {
$this->moveFromCacheFallback($sourceCache, $sourcePath, $targetPath);
@@ -587,11 +666,15 @@ class Cache implements ICache {
* remove all entries for files that are stored on the storage from the cache
*/
public function clear() {
- $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `storage` = ?';
- $this->connection->executeQuery($sql, array($this->getNumericStorageId()));
+ $query = $this->getQueryBuilder();
+ $query->delete('filecache')
+ ->whereStorageId();
+ $query->execute();
- $sql = 'DELETE FROM `*PREFIX*storages` WHERE `id` = ?';
- $this->connection->executeQuery($sql, array($this->storageId));
+ $query = $this->connection->getQueryBuilder();
+ $query->delete('storages')
+ ->where($query->expr()->eq('id', $query->createNamedParameter($this->storageId)));
+ $query->execute();
}
/**
@@ -610,11 +693,14 @@ class Cache implements ICache {
// normalize file
$file = $this->normalize($file);
- $pathHash = md5($file);
- $sql = 'SELECT `size` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?';
- $result = $this->connection->executeQuery($sql, array($this->getNumericStorageId(), $pathHash));
- if ($row = $result->fetch()) {
- if ((int)$row['size'] === -1) {
+ $query = $this->getQueryBuilder();
+ $query->select('size')
+ ->from('filecache')
+ ->whereStorageId()
+ ->wherePath($file);
+ $size = $query->execute()->fetchColumn();
+ if ($size !== false) {
+ if ((int)$size === -1) {
return self::SHALLOW;
} else {
return self::COMPLETE;
@@ -642,18 +728,14 @@ class Cache implements ICache {
return [];
}
+ $query = $this->getQueryBuilder();
+ $query->selectFileCache()
+ ->whereStorageId()
+ ->andWhere($query->expr()->iLike('name', $query->createNamedParameter($pattern)));
- $sql = '
- SELECT `fileid`, `storage`, `path`, `parent`, `name`,
- `mimetype`, `storage_mtime`, `mimepart`, `size`, `mtime`,
- `encrypted`, `etag`, `permissions`, `checksum`
- FROM `*PREFIX*filecache`
- WHERE `storage` = ? AND `name` ILIKE ?';
- $result = $this->connection->executeQuery($sql,
- [$this->getNumericStorageId(), $pattern]
- );
-
- return $this->searchResultToCacheEntries($result);
+ return array_map(function (array $data) {
+ return self::cacheEntryFromData($data, $this->mimetypeLoader);
+ }, $query->execute()->fetchAll());
}
/**
@@ -676,26 +758,29 @@ class Cache implements ICache {
* @return ICacheEntry[] an array of cache entries where the mimetype matches the search
*/
public function searchByMime($mimetype) {
+ $mimeId = $this->mimetypeLoader->getId($mimetype);
+
+ $query = $this->getQueryBuilder();
+ $query->selectFileCache()
+ ->whereStorageId();
+
if (strpos($mimetype, '/')) {
- $where = '`mimetype` = ?';
+ $query->andWhere($query->expr()->eq('mimetype', $query->createNamedParameter($mimeId, IQueryBuilder::PARAM_INT)));
} else {
- $where = '`mimepart` = ?';
+ $query->andWhere($query->expr()->eq('mimepart', $query->createNamedParameter($mimeId, IQueryBuilder::PARAM_INT)));
}
- $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `storage_mtime`, `mtime`, `encrypted`, `etag`, `permissions`, `checksum`
- FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?';
- $mimetype = $this->mimetypeLoader->getId($mimetype);
- $result = $this->connection->executeQuery($sql, array($mimetype, $this->getNumericStorageId()));
- return $this->searchResultToCacheEntries($result);
+ return array_map(function (array $data) {
+ return self::cacheEntryFromData($data, $this->mimetypeLoader);
+ }, $query->execute()->fetchAll());
}
public function searchQuery(ISearchQuery $searchQuery) {
- $builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
+ $builder = $this->getQueryBuilder();
- $query = $builder->select(['fileid', 'storage', 'path', 'parent', 'name', 'mimetype', 'mimepart', 'size', 'mtime', 'storage_mtime', 'encrypted', 'etag', 'permissions', 'checksum'])
- ->from('filecache', 'file');
+ $query = $builder->selectFileCache('file');
- $query->where($builder->expr()->eq('storage', $builder->createNamedParameter($this->getNumericStorageId())));
+ $query->whereStorageId();
if ($this->querySearchHelper->shouldJoinTags($searchQuery->getSearchOperation())) {
$query
@@ -755,10 +840,13 @@ class Cache implements ICache {
*/
public function getIncompleteChildrenCount($fileId) {
if ($fileId > -1) {
- $sql = 'SELECT count(*)
- FROM `*PREFIX*filecache` WHERE `parent` = ? AND size = -1';
- $result = $this->connection->executeQuery($sql, [$fileId]);
- return (int)$result->fetchColumn();
+ $query = $this->getQueryBuilder();
+ $query->select($query->func()->count())
+ ->from('filecache')
+ ->whereParent($fileId)
+ ->andWhere($query->expr()->lt('size', $query->createNamedParameter(0, IQueryBuilder::PARAM_INT)));
+
+ return (int)$query->execute()->fetchColumn();
}
return -1;
}
@@ -775,14 +863,17 @@ class Cache implements ICache {
if (is_null($entry) or !isset($entry['fileid'])) {
$entry = $this->get($path);
}
- if (isset($entry['mimetype']) && $entry['mimetype'] === 'httpd/unix-directory') {
+ if (isset($entry['mimetype']) && $entry['mimetype'] === FileInfo::MIMETYPE_FOLDER) {
$id = $entry['fileid'];
- $sql = 'SELECT SUM(`size`) AS f1, MIN(`size`) AS f2 ' .
- 'FROM `*PREFIX*filecache` ' .
- 'WHERE `parent` = ? AND `storage` = ?';
- $result = $this->connection->executeQuery($sql, array($id, $this->getNumericStorageId()));
- if ($row = $result->fetch()) {
- $result->closeCursor();
+
+ $query = $this->getQueryBuilder();
+ $query->selectAlias($query->func()->sum('size'), 'f1')
+ ->selectAlias($query->func()->min('size'), 'f2')
+ ->from('filecache')
+ ->whereStorageId()
+ ->whereParent($id);
+
+ if ($row = $query->execute()->fetch()) {
list($sum, $min) = array_values($row);
$sum = 0 + $sum;
$min = 0 + $min;
@@ -791,15 +882,9 @@ class Cache implements ICache {
} else {
$totalSize = $sum;
}
- $update = array();
if ($entry['size'] !== $totalSize) {
- $update['size'] = $totalSize;
+ $this->update($id, ['size' => $totalSize]);
}
- if (count($update) > 0) {
- $this->update($id, $update);
- }
- } else {
- $result->closeCursor();
}
}
return $totalSize;
@@ -811,13 +896,14 @@ class Cache implements ICache {
* @return int[]
*/
public function getAll() {
- $sql = 'SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ?';
- $result = $this->connection->executeQuery($sql, array($this->getNumericStorageId()));
- $ids = array();
- while ($row = $result->fetch()) {
- $ids[] = $row['fileid'];
- }
- return $ids;
+ $query = $this->getQueryBuilder();
+ $query->select('fileid')
+ ->from('filecache')
+ ->whereStorageId();
+
+ return array_map(function ($id) {
+ return (int)$id;
+ }, $query->execute()->fetchAll(\PDO::FETCH_COLUMN));
}
/**
@@ -830,14 +916,14 @@ class Cache implements ICache {
* @return string|bool the path of the folder or false when no folder matched
*/
public function getIncomplete() {
- $query = $this->connection->prepare('SELECT `path` FROM `*PREFIX*filecache`'
- . ' WHERE `storage` = ? AND `size` = -1 ORDER BY `fileid` DESC', 1);
- $query->execute([$this->getNumericStorageId()]);
- if ($row = $query->fetch()) {
- return $row['path'];
- } else {
- return false;
- }
+ $query = $this->getQueryBuilder();
+ $query->select('path')
+ ->from('filecache')
+ ->whereStorageId()
+ ->andWhere($query->expr()->lt('size', $query->createNamedParameter(0, IQueryBuilder::PARAM_INT)))
+ ->orderBy('fileid', 'DESC');
+
+ return $query->execute()->fetchColumn();
}
/**
@@ -847,17 +933,14 @@ class Cache implements ICache {
* @return string|null the path of the file (relative to the storage) or null if a file with the given id does not exists within this cache
*/
public function getPathById($id) {
- $sql = 'SELECT `path` FROM `*PREFIX*filecache` WHERE `fileid` = ? AND `storage` = ?';
- $result = $this->connection->executeQuery($sql, array($id, $this->getNumericStorageId()));
- if ($row = $result->fetch()) {
- // Oracle stores empty strings as null...
- if ($row['path'] === null) {
- return '';
- }
- return $row['path'];
- } else {
- return null;
- }
+ $query = $this->getQueryBuilder();
+ $query->select('path')
+ ->from('filecache')
+ ->whereStorageId()
+ ->whereFileId($id);
+
+ $path = $query->execute()->fetchColumn();
+ return $path === false ? null : $path;
}
/**
@@ -866,14 +949,15 @@ class Cache implements ICache {
* instead does a global search in the cache table
*
* @param int $id
- * @deprecated use getPathById() instead
* @return array first element holding the storage id, second the path
+ * @deprecated use getPathById() instead
*/
static public function getById($id) {
- $connection = \OC::$server->getDatabaseConnection();
- $sql = 'SELECT `storage`, `path` FROM `*PREFIX*filecache` WHERE `fileid` = ?';
- $result = $connection->executeQuery($sql, array($id));
- if ($row = $result->fetch()) {
+ $query = \OC::$server->getDatabaseConnection()->getQueryBuilder();
+ $query->select('path', 'storage')
+ ->from('filecache')
+ ->where($query->expr()->eq('fileid', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
+ if ($row = $query->execute()->fetch()) {
$numericId = $row['storage'];
$path = $row['path'];
} else {
@@ -881,7 +965,7 @@ class Cache implements ICache {
}
if ($id = Storage::getStorageId($numericId)) {
- return array($id, $path);
+ return [$id, $path];
} else {
return null;
}
diff --git a/lib/private/Files/Cache/CacheEntry.php b/lib/private/Files/Cache/CacheEntry.php
index 4a2579a88f8..176a0bf27ed 100644
--- a/lib/private/Files/Cache/CacheEntry.php
+++ b/lib/private/Files/Cache/CacheEntry.php
@@ -109,6 +109,18 @@ class CacheEntry implements ICacheEntry, \ArrayAccess {
return isset($this->data['encrypted']) && $this->data['encrypted'];
}
+ public function getMetadataEtag(): ?string {
+ return $this->data['metadata_etag'];
+ }
+
+ public function getCreationTime(): ?int {
+ return $this->data['creation_time'];
+ }
+
+ public function getUploadTime(): ?int {
+ return $this->data['upload_time'];
+ }
+
public function getData() {
return $this->data;
}
diff --git a/lib/private/Files/Cache/CacheQueryBuilder.php b/lib/private/Files/Cache/CacheQueryBuilder.php
new file mode 100644
index 00000000000..a5ff2129de8
--- /dev/null
+++ b/lib/private/Files/Cache/CacheQueryBuilder.php
@@ -0,0 +1,92 @@
+<?php declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2019 Robin Appelman <robin@icewind.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Files\Cache;
+
+use OC\DB\QueryBuilder\QueryBuilder;
+use OC\SystemConfig;
+use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\IDBConnection;
+use OCP\ILogger;
+
+/**
+ * Query builder with commonly used helpers for filecache queries
+ */
+class CacheQueryBuilder extends QueryBuilder {
+ private $cache;
+ private $alias = null;
+
+ public function __construct(IDBConnection $connection, SystemConfig $systemConfig, ILogger $logger, Cache $cache) {
+ parent::__construct($connection, $systemConfig, $logger);
+
+ $this->cache = $cache;
+ }
+
+ public function selectFileCache(string $alias = null) {
+ $name = $alias ? $alias : 'filecache';
+ $this->select("$name.fileid", 'storage', 'path', 'path_hash', "$name.parent", 'name', 'mimetype', 'mimepart', 'size', 'mtime',
+ 'storage_mtime', 'encrypted', 'etag', 'permissions', 'checksum', 'metadata_etag', 'creation_time', 'upload_time')
+ ->from('filecache', $name)
+ ->leftJoin($name, 'filecache_extended', 'fe', $this->expr()->eq("$name.fileid", 'fe.fileid'));
+
+ $this->alias = $name;
+
+ return $this;
+ }
+
+ public function whereStorageId() {
+ $this->andWhere($this->expr()->eq('storage', $this->createNamedParameter($this->cache->getNumericStorageId(), IQueryBuilder::PARAM_INT)));
+
+ return $this;
+ }
+
+ public function whereFileId(int $fileId) {
+ $alias = $this->alias;
+ if ($alias) {
+ $alias .= '.';
+ } else {
+ $alias = '';
+ }
+
+ $this->andWhere($this->expr()->eq("{$alias}fileid", $this->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)));
+
+ return $this;
+ }
+
+ public function wherePath(string $path) {
+ $this->andWhere($this->expr()->eq('path_hash', $this->createNamedParameter(md5($path))));
+
+ return $this;
+ }
+
+ public function whereParent(int $parent) {
+ $alias = $this->alias;
+ if ($alias) {
+ $alias .= '.';
+ } else {
+ $alias = '';
+ }
+
+ $this->andWhere($this->expr()->eq("{$alias}parent", $this->createNamedParameter($parent, IQueryBuilder::PARAM_INT)));
+
+ return $this;
+ }
+}
diff --git a/lib/private/Files/Cache/MoveFromCacheTrait.php b/lib/private/Files/Cache/MoveFromCacheTrait.php
index a814a081dca..e9b41bd9b37 100644
--- a/lib/private/Files/Cache/MoveFromCacheTrait.php
+++ b/lib/private/Files/Cache/MoveFromCacheTrait.php
@@ -82,7 +82,10 @@ trait MoveFromCacheTrait {
'mimepart' => $entry->getMimePart(),
'etag' => $entry->getEtag(),
'permissions' => $entry->getPermissions(),
- 'encrypted' => $entry->isEncrypted()
+ 'encrypted' => $entry->isEncrypted(),
+ 'creation_time' => $entry->getCreationTime(),
+ 'upload_time' => $entry->getUploadTime(),
+ 'metadata_etag' => $entry->getMetadataEtag(),
];
}
}
diff --git a/lib/private/Files/FileInfo.php b/lib/private/Files/FileInfo.php
index 19b95cd0355..93f876db17b 100644
--- a/lib/private/Files/FileInfo.php
+++ b/lib/private/Files/FileInfo.php
@@ -406,4 +406,12 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
public function getExtension(): string {
return pathinfo($this->getName(), PATHINFO_EXTENSION);
}
+
+ public function getCreationTime(): int {
+ return (int) $this->data['creation_time'];
+ }
+
+ public function getUploadTime(): int {
+ return (int) $this->data['upload_time'];
+ }
}
diff --git a/lib/private/Files/Node/LazyRoot.php b/lib/private/Files/Node/LazyRoot.php
index 01b4ca52765..f5d8cdc91a9 100644
--- a/lib/private/Files/Node/LazyRoot.php
+++ b/lib/private/Files/Node/LazyRoot.php
@@ -480,4 +480,18 @@ class LazyRoot implements IRootFolder {
public function getRecent($limit, $offset = 0) {
return $this->__call(__FUNCTION__, func_get_args());
}
+
+ /**
+ * @inheritDoc
+ */
+ public function getCreationTime(): int {
+ return $this->__call(__FUNCTION__, func_get_args());
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getUploadTime(): int {
+ return $this->__call(__FUNCTION__, func_get_args());
+ }
}
diff --git a/lib/private/Files/Node/Node.php b/lib/private/Files/Node/Node.php
index c440dd4a8f1..95d16cf5c99 100644
--- a/lib/private/Files/Node/Node.php
+++ b/lib/private/Files/Node/Node.php
@@ -444,4 +444,12 @@ class Node implements \OCP\Files\Node {
}
}
+ public function getCreationTime(): int {
+ return $this->getFileInfo()->getCreationTime();
+ }
+
+ public function getUploadTime(): int {
+ return $this->getFileInfo()->getUploadTime();
+ }
+
}
diff --git a/lib/public/DB/QueryBuilder/IFunctionBuilder.php b/lib/public/DB/QueryBuilder/IFunctionBuilder.php
index 066be470150..861a576914a 100644
--- a/lib/public/DB/QueryBuilder/IFunctionBuilder.php
+++ b/lib/public/DB/QueryBuilder/IFunctionBuilder.php
@@ -104,7 +104,7 @@ interface IFunctionBuilder {
* @return IQueryFunction
* @since 14.0.0
*/
- public function count($count, $alias = '');
+ public function count($count = '', $alias = '');
/**
* Takes the maximum of all rows in a column
diff --git a/lib/public/DB/QueryBuilder/IQueryBuilder.php b/lib/public/DB/QueryBuilder/IQueryBuilder.php
index 7fea31f4688..fe5182f21b9 100644
--- a/lib/public/DB/QueryBuilder/IQueryBuilder.php
+++ b/lib/public/DB/QueryBuilder/IQueryBuilder.php
@@ -180,7 +180,7 @@ interface IQueryBuilder {
* @param mixed $value The parameter value.
* @param string|null|int $type One of the IQueryBuilder::PARAM_* constants.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function setParameter($key, $value, $type = null);
@@ -202,7 +202,7 @@ interface IQueryBuilder {
* @param array $params The query parameters to set.
* @param array $types The query parameters types to set.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function setParameters(array $params, array $types = array());
@@ -248,7 +248,7 @@ interface IQueryBuilder {
*
* @param integer $firstResult The first result to return.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function setFirstResult($firstResult);
@@ -267,7 +267,7 @@ interface IQueryBuilder {
*
* @param integer $maxResults The maximum number of results to retrieve.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function setMaxResults($maxResults);
@@ -294,7 +294,7 @@ interface IQueryBuilder {
*
* @param mixed ...$selects The selection expressions.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function select(...$selects);
@@ -312,7 +312,7 @@ interface IQueryBuilder {
* @param mixed $select The selection expressions.
* @param string $alias The column alias used in the constructed query.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.1
*/
public function selectAlias($select, $alias);
@@ -328,7 +328,7 @@ interface IQueryBuilder {
*
* @param mixed $select The selection expressions.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 9.0.0
*/
public function selectDistinct($select);
@@ -346,7 +346,7 @@ interface IQueryBuilder {
*
* @param mixed ...$select The selection expression.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function addSelect(...$select);
@@ -365,7 +365,7 @@ interface IQueryBuilder {
* @param string $delete The table whose rows are subject to the deletion.
* @param string $alias The table alias used in the constructed query.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function delete($delete = null, $alias = null);
@@ -384,7 +384,7 @@ interface IQueryBuilder {
* @param string $update The table whose rows are subject to the update.
* @param string $alias The table alias used in the constructed query.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function update($update = null, $alias = null);
@@ -406,7 +406,7 @@ interface IQueryBuilder {
*
* @param string $insert The table into which the rows should be inserted.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function insert($insert = null);
@@ -424,7 +424,7 @@ interface IQueryBuilder {
* @param string $from The table.
* @param string|null $alias The alias of the table.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function from($from, $alias = null);
@@ -444,7 +444,7 @@ interface IQueryBuilder {
* @param string $alias The alias of the join table.
* @param string $condition The condition for the join.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function join($fromAlias, $join, $alias, $condition = null);
@@ -464,7 +464,7 @@ interface IQueryBuilder {
* @param string $alias The alias of the join table.
* @param string $condition The condition for the join.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function innerJoin($fromAlias, $join, $alias, $condition = null);
@@ -484,7 +484,7 @@ interface IQueryBuilder {
* @param string $alias The alias of the join table.
* @param string $condition The condition for the join.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function leftJoin($fromAlias, $join, $alias, $condition = null);
@@ -504,7 +504,7 @@ interface IQueryBuilder {
* @param string $alias The alias of the join table.
* @param string $condition The condition for the join.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function rightJoin($fromAlias, $join, $alias, $condition = null);
@@ -522,7 +522,7 @@ interface IQueryBuilder {
* @param string $key The column to set.
* @param string $value The value, expression, placeholder, etc.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function set($key, $value);
@@ -551,7 +551,7 @@ interface IQueryBuilder {
*
* @param mixed $predicates The restriction predicates.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function where(...$predicates);
@@ -570,7 +570,7 @@ interface IQueryBuilder {
*
* @param mixed ...$where The query restrictions.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*
* @see where()
* @since 8.2.0
@@ -591,7 +591,7 @@ interface IQueryBuilder {
*
* @param mixed ...$where The WHERE statement.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*
* @see where()
* @since 8.2.0
@@ -611,7 +611,7 @@ interface IQueryBuilder {
*
* @param mixed ...$groupBys The grouping expression.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function groupBy(...$groupBys);
@@ -629,7 +629,7 @@ interface IQueryBuilder {
*
* @param mixed ...$groupBy The grouping expression.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function addGroupBy(...$groupBy);
@@ -651,7 +651,7 @@ interface IQueryBuilder {
* @param string $column The column into which the value should be inserted.
* @param string $value The value that should be inserted into the column.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function setValue($column, $value);
@@ -673,7 +673,7 @@ interface IQueryBuilder {
*
* @param array $values The values to specify for the insert query indexed by column names.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function values(array $values);
@@ -684,7 +684,7 @@ interface IQueryBuilder {
*
* @param mixed ...$having The restriction over the groups.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function having(...$having);
@@ -695,7 +695,7 @@ interface IQueryBuilder {
*
* @param mixed ...$having The restriction to append.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function andHaving(...$having);
@@ -706,7 +706,7 @@ interface IQueryBuilder {
*
* @param mixed ...$having The restriction to add.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function orHaving(...$having);
@@ -718,7 +718,7 @@ interface IQueryBuilder {
* @param string $sort The ordering expression.
* @param string $order The ordering direction.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function orderBy($sort, $order = null);
@@ -729,7 +729,7 @@ interface IQueryBuilder {
* @param string $sort The ordering expression.
* @param string $order The ordering direction.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function addOrderBy($sort, $order = null);
@@ -757,7 +757,7 @@ interface IQueryBuilder {
*
* @param array|null $queryPartNames
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function resetQueryParts($queryPartNames = null);
@@ -767,7 +767,7 @@ interface IQueryBuilder {
*
* @param string $queryPartName
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
* @since 8.2.0
*/
public function resetQueryPart($queryPartName);
diff --git a/lib/public/Files/Cache/ICacheEntry.php b/lib/public/Files/Cache/ICacheEntry.php
index bbc9982935e..5223720b006 100644
--- a/lib/public/Files/Cache/ICacheEntry.php
+++ b/lib/public/Files/Cache/ICacheEntry.php
@@ -132,4 +132,28 @@ interface ICacheEntry {
* @since 9.0.0
*/
public function isEncrypted();
+
+ /**
+ * Get the metadata etag for the file
+ *
+ * @return string | null
+ * @since 18.0.0
+ */
+ public function getMetadataEtag(): ?string;
+
+ /**
+ * Get the last modified date as unix timestamp
+ *
+ * @return int | null
+ * @since 18.0.0
+ */
+ public function getCreationTime(): ?int;
+
+ /**
+ * Get the last modified date as unix timestamp
+ *
+ * @return int | null
+ * @since 18.0.0
+ */
+ public function getUploadTime(): ?int;
}
diff --git a/lib/public/Files/FileInfo.php b/lib/public/Files/FileInfo.php
index c256f0980f0..4d9e76b27f3 100644
--- a/lib/public/Files/FileInfo.php
+++ b/lib/public/Files/FileInfo.php
@@ -268,4 +268,30 @@ interface FileInfo {
* @since 15.0.0
*/
public function getExtension(): string;
+
+ /**
+ * Get the creation date as unix timestamp
+ *
+ * If the creation time is not known, 0 will be returned
+ *
+ * creation time is not set automatically by the server and is generally only available
+ * for files uploaded by the sync clients
+ *
+ * @return int
+ * @since 18.0.0
+ */
+ public function getCreationTime(): int;
+
+ /**
+ * Get the upload date as unix timestamp
+ *
+ * If the upload time is not known, 0 will be returned
+ *
+ * Upload time will be set automatically by the server for files uploaded over DAV
+ * files created by Nextcloud apps generally do not have an the upload time set
+ *
+ * @return int
+ * @since 18.0.0
+ */
+ public function getUploadTime(): int;
}
diff --git a/tests/lib/Files/Cache/CacheTest.php b/tests/lib/Files/Cache/CacheTest.php
index eaea1692fe2..ccdfbbd065b 100644
--- a/tests/lib/Files/Cache/CacheTest.php
+++ b/tests/lib/Files/Cache/CacheTest.php
@@ -707,6 +707,76 @@ class CacheTest extends \Test\TestCase {
}
}
+ public function testExtended() {
+ $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory'];
+ $this->cache->put("", $folderData);
+
+ $data = ['size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain', 'creation_time' => 20];
+ $id1 = $this->cache->put("foo1", $data);
+ $data = ['size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain', 'upload_time' => 30];
+ $this->cache->put("foo2", $data);
+ $data = ['size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain', 'metadata_etag' => 'foo'];
+ $this->cache->put("foo3", $data);
+ $data = ['size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain'];
+ $id4 = $this->cache->put("foo4", $data);
+
+ $entry = $this->cache->get($id1);
+ $this->assertEquals(20, $entry->getCreationTime());
+ $this->assertEquals(0, $entry->getUploadTime());
+ $this->assertEquals(null, $entry->getMetadataEtag());
+
+ $entries = $this->cache->getFolderContents("");
+ $this->assertCount(4, $entries);
+
+ $this->assertEquals("foo1", $entries[0]->getName());
+ $this->assertEquals("foo2", $entries[1]->getName());
+ $this->assertEquals("foo3", $entries[2]->getName());
+ $this->assertEquals("foo4", $entries[3]->getName());
+
+ $this->assertEquals(20, $entries[0]->getCreationTime());
+ $this->assertEquals(0, $entries[0]->getUploadTime());
+ $this->assertEquals(null, $entries[0]->getMetadataEtag());
+
+ $this->assertEquals(0, $entries[1]->getCreationTime());
+ $this->assertEquals(30, $entries[1]->getUploadTime());
+ $this->assertEquals(null, $entries[1]->getMetadataEtag());
+
+ $this->assertEquals(0, $entries[2]->getCreationTime());
+ $this->assertEquals(0, $entries[2]->getUploadTime());
+ $this->assertEquals('foo', $entries[2]->getMetadataEtag());
+
+ $this->assertEquals(0, $entries[3]->getCreationTime());
+ $this->assertEquals(0, $entries[3]->getUploadTime());
+ $this->assertEquals(null, $entries[3]->getMetadataEtag());
+
+ $this->cache->update($id1, ['upload_time' => 25]);
+
+ $entry = $this->cache->get($id1);
+ $this->assertEquals(20, $entry->getCreationTime());
+ $this->assertEquals(25, $entry->getUploadTime());
+ $this->assertEquals(null, $entry->getMetadataEtag());
+
+ $this->cache->put("sub", $folderData);
+
+ $this->cache->move("foo1", "sub/foo1");
+
+ $entries = $this->cache->getFolderContents("sub");
+ $this->assertCount(1, $entries);
+
+ $this->assertEquals(20, $entries[0]->getCreationTime());
+ $this->assertEquals(25, $entries[0]->getUploadTime());
+ $this->assertEquals(null, $entries[0]->getMetadataEtag());
+
+ $this->cache->update($id4, ['upload_time' => 25]);
+
+ $entry = $this->cache->get($id4);
+ $this->assertEquals(0, $entry->getCreationTime());
+ $this->assertEquals(25, $entry->getUploadTime());
+ $this->assertEquals(null, $entry->getMetadataEtag());
+
+ $this->cache->remove("sub");
+ }
+
protected function tearDown() {
if ($this->cache) {
$this->cache->clear();
diff --git a/tests/lib/Files/ViewTest.php b/tests/lib/Files/ViewTest.php
index 4697dbe89d8..5c37c9a0e93 100644
--- a/tests/lib/Files/ViewTest.php
+++ b/tests/lib/Files/ViewTest.php
@@ -25,6 +25,7 @@ use OCP\Share;
use OCP\Util;
use Test\TestMoveableMountPoint;
use Test\HookHelper;
+use Test\Traits\UserTrait;
class TemporaryNoTouch extends Temporary {
public function touch($path, $mtime = null) {
@@ -60,10 +61,12 @@ class TemporaryNoLocal extends Temporary {
* @package Test\Files
*/
class ViewTest extends \Test\TestCase {
+ use UserTrait;
+
/**
* @var \OC\Files\Storage\Storage[] $storages
*/
- private $storages = array();
+ private $storages = [];
/**
* @var string
@@ -138,9 +141,9 @@ class ViewTest extends \Test\TestCase {
$storage2 = $this->getTestStorage();
$storage3 = $this->getTestStorage();
$root = self::getUniqueID('/');
- Filesystem::mount($storage1, array(), $root . '/');
- Filesystem::mount($storage2, array(), $root . '/substorage');
- Filesystem::mount($storage3, array(), $root . '/folder/anotherstorage');
+ Filesystem::mount($storage1, [], $root . '/');
+ Filesystem::mount($storage2, [], $root . '/substorage');
+ Filesystem::mount($storage3, [], $root . '/folder/anotherstorage');
$textSize = strlen("dummy file data\n");
$imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo/logo.png');
$storageSize = $textSize * 2 + $imageSize;
@@ -204,13 +207,13 @@ class ViewTest extends \Test\TestCase {
$cachedData = $rootView->getFileInfo('/foo.txt');
$this->assertFalse($cachedData['encrypted']);
- $id = $rootView->putFileInfo('/foo.txt', array('encrypted' => true));
+ $id = $rootView->putFileInfo('/foo.txt', ['encrypted' => true]);
$cachedData = $rootView->getFileInfo('/foo.txt');
$this->assertTrue($cachedData['encrypted']);
$this->assertEquals($cachedData['fileid'], $id);
$this->assertFalse($rootView->getFileInfo('/non/existing'));
- $this->assertEquals(array(), $rootView->getDirectoryContent('/non/existing'));
+ $this->assertEquals([], $rootView->getDirectoryContent('/non/existing'));
}
/**
@@ -220,9 +223,9 @@ class ViewTest extends \Test\TestCase {
$storage1 = $this->getTestStorage();
$storage2 = $this->getTestStorage();
$storage3 = $this->getTestStorage();
- Filesystem::mount($storage1, array(), '/');
- Filesystem::mount($storage2, array(), '/substorage');
- Filesystem::mount($storage3, array(), '/folder/anotherstorage');
+ Filesystem::mount($storage1, [], '/');
+ Filesystem::mount($storage2, [], '/substorage');
+ Filesystem::mount($storage3, [], '/folder/anotherstorage');
$rootView = new View('');
@@ -262,8 +265,8 @@ class ViewTest extends \Test\TestCase {
$storage1 = $this->getTestStorage(false);
$storage2 = $this->getTestStorage();
$storage1->mkdir('substorage');
- Filesystem::mount($storage1, array(), '/');
- Filesystem::mount($storage2, array(), '/substorage');
+ Filesystem::mount($storage1, [], '/');
+ Filesystem::mount($storage2, [], '/substorage');
$rootView = new View('');
$folderContent = $rootView->getDirectoryContent('/');
@@ -292,8 +295,8 @@ class ViewTest extends \Test\TestCase {
$storage1 = $this->getTestStorage();
$storage2 = $this->getTestStorage();
- Filesystem::mount($storage1, array(), '/');
- Filesystem::mount($storage2, array(), '/mount');
+ Filesystem::mount($storage1, [], '/');
+ Filesystem::mount($storage2, [], '/mount');
$view = new View('/');
@@ -313,7 +316,7 @@ class ViewTest extends \Test\TestCase {
public function testCacheIncompleteFolder() {
$storage1 = $this->getTestStorage(false);
Filesystem::clearMounts();
- Filesystem::mount($storage1, array(), '/incomplete');
+ Filesystem::mount($storage1, [], '/incomplete');
$rootView = new View('/incomplete');
$entries = $rootView->getDirectoryContent('/');
@@ -327,8 +330,8 @@ class ViewTest extends \Test\TestCase {
public function testAutoScan() {
$storage1 = $this->getTestStorage(false);
$storage2 = $this->getTestStorage(false);
- Filesystem::mount($storage1, array(), '/');
- Filesystem::mount($storage2, array(), '/substorage');
+ Filesystem::mount($storage1, [], '/');
+ Filesystem::mount($storage2, [], '/substorage');
$textSize = strlen("dummy file data\n");
$rootView = new View('');
@@ -349,15 +352,15 @@ class ViewTest extends \Test\TestCase {
$storage1 = $this->getTestStorage();
$storage2 = $this->getTestStorage();
$storage3 = $this->getTestStorage();
- Filesystem::mount($storage1, array(), '/');
- Filesystem::mount($storage2, array(), '/substorage');
- Filesystem::mount($storage3, array(), '/folder/anotherstorage');
+ Filesystem::mount($storage1, [], '/');
+ Filesystem::mount($storage2, [], '/substorage');
+ Filesystem::mount($storage3, [], '/folder/anotherstorage');
$rootView = new View('');
$results = $rootView->search('foo');
$this->assertCount(6, $results);
- $paths = array();
+ $paths = [];
foreach ($results as $result) {
$this->assertEquals($result['path'], Filesystem::normalizePath($result['path']));
$paths[] = $result['path'];
@@ -372,7 +375,7 @@ class ViewTest extends \Test\TestCase {
$folderView = new View('/folder');
$results = $folderView->search('bar');
$this->assertCount(2, $results);
- $paths = array();
+ $paths = [];
foreach ($results as $result) {
$paths[] = $result['path'];
}
@@ -381,7 +384,7 @@ class ViewTest extends \Test\TestCase {
$results = $folderView->search('foo');
$this->assertCount(2, $results);
- $paths = array();
+ $paths = [];
foreach ($results as $result) {
$paths[] = $result['path'];
}
@@ -397,7 +400,7 @@ class ViewTest extends \Test\TestCase {
*/
public function testWatcher() {
$storage1 = $this->getTestStorage();
- Filesystem::mount($storage1, array(), '/');
+ Filesystem::mount($storage1, [], '/');
$storage1->getWatcher()->setPolicy(Watcher::CHECK_ALWAYS);
$rootView = new View('');
@@ -405,7 +408,7 @@ class ViewTest extends \Test\TestCase {
$cachedData = $rootView->getFileInfo('foo.txt');
$this->assertEquals(16, $cachedData['size']);
- $rootView->putFileInfo('foo.txt', array('storage_mtime' => 10));
+ $rootView->putFileInfo('foo.txt', ['storage_mtime' => 10]);
$storage1->file_put_contents('foo.txt', 'foo');
clearstatcache();
@@ -441,8 +444,8 @@ class ViewTest extends \Test\TestCase {
}
public function copyBetweenStorages($storage1, $storage2) {
- Filesystem::mount($storage1, array(), '/');
- Filesystem::mount($storage2, array(), '/substorage');
+ Filesystem::mount($storage1, [], '/');
+ Filesystem::mount($storage2, [], '/substorage');
$rootView = new View('');
$rootView->mkdir('substorage/emptyfolder');
@@ -487,8 +490,8 @@ class ViewTest extends \Test\TestCase {
}
public function moveBetweenStorages($storage1, $storage2) {
- Filesystem::mount($storage1, array(), '/');
- Filesystem::mount($storage2, array(), '/substorage');
+ Filesystem::mount($storage1, [], '/');
+ Filesystem::mount($storage2, [], '/substorage');
$rootView = new View('');
$rootView->rename('foo.txt', 'substorage/folder/foo.txt');
@@ -506,8 +509,8 @@ class ViewTest extends \Test\TestCase {
public function testUnlink() {
$storage1 = $this->getTestStorage();
$storage2 = $this->getTestStorage();
- Filesystem::mount($storage1, array(), '/');
- Filesystem::mount($storage2, array(), '/substorage');
+ Filesystem::mount($storage1, [], '/');
+ Filesystem::mount($storage2, [], '/substorage');
$rootView = new View('');
$rootView->file_put_contents('/foo.txt', 'asd');
@@ -552,8 +555,8 @@ class ViewTest extends \Test\TestCase {
public function testUnlinkRootMustFail() {
$storage1 = $this->getTestStorage();
$storage2 = $this->getTestStorage();
- Filesystem::mount($storage1, array(), '/');
- Filesystem::mount($storage2, array(), '/substorage');
+ Filesystem::mount($storage1, [], '/');
+ Filesystem::mount($storage2, [], '/substorage');
$rootView = new View('');
$rootView->file_put_contents('/foo.txt', 'asd');
@@ -571,7 +574,7 @@ class ViewTest extends \Test\TestCase {
public function testTouch() {
$storage = $this->getTestStorage(true, TemporaryNoTouch::class);
- Filesystem::mount($storage, array(), '/');
+ Filesystem::mount($storage, [], '/');
$rootView = new View('');
$oldCachedData = $rootView->getFileInfo('foo.txt');
@@ -582,7 +585,7 @@ class ViewTest extends \Test\TestCase {
$this->assertEquals(500, $cachedData['mtime']);
$this->assertEquals($oldCachedData['storage_mtime'], $cachedData['storage_mtime']);
- $rootView->putFileInfo('foo.txt', array('storage_mtime' => 1000)); //make sure the watcher detects the change
+ $rootView->putFileInfo('foo.txt', ['storage_mtime' => 1000]); //make sure the watcher detects the change
$rootView->file_put_contents('foo.txt', 'asd');
$cachedData = $rootView->getFileInfo('foo.txt');
$this->assertGreaterThanOrEqual($oldCachedData['mtime'], $cachedData['mtime']);
@@ -595,7 +598,7 @@ class ViewTest extends \Test\TestCase {
public function testTouchFloat() {
$storage = $this->getTestStorage(true, TemporaryNoTouch::class);
- Filesystem::mount($storage, array(), '/');
+ Filesystem::mount($storage, [], '/');
$rootView = new View('');
$oldCachedData = $rootView->getFileInfo('foo.txt');
@@ -613,8 +616,8 @@ class ViewTest extends \Test\TestCase {
$storage1 = $this->getTestStorage();
$storage2 = $this->getTestStorage();
$defaultRoot = Filesystem::getRoot();
- Filesystem::mount($storage1, array(), '/');
- Filesystem::mount($storage2, array(), $defaultRoot . '/substorage');
+ Filesystem::mount($storage1, [], '/');
+ Filesystem::mount($storage2, [], $defaultRoot . '/substorage');
\OC_Hook::connect('OC_Filesystem', 'post_write', $this, 'dummyHook');
$rootView = new View('');
@@ -636,7 +639,7 @@ class ViewTest extends \Test\TestCase {
public function testSearchNotOutsideView() {
$storage1 = $this->getTestStorage();
- Filesystem::mount($storage1, array(), '/');
+ Filesystem::mount($storage1, [], '/');
$storage1->rename('folder', 'foo');
$scanner = $storage1->getScanner();
$scanner->scan('');
@@ -656,7 +659,7 @@ class ViewTest extends \Test\TestCase {
/**
* @var \OC\Files\Storage\Storage $storage
*/
- $storage = new $class(array());
+ $storage = new $class([]);
$textData = "dummy file data\n";
$imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo/logo.png');
$storage->mkdir('folder');
@@ -679,8 +682,8 @@ class ViewTest extends \Test\TestCase {
$storage1 = $this->getTestStorage();
$storage2 = $this->getTestStorage();
$defaultRoot = Filesystem::getRoot();
- Filesystem::mount($storage1, array(), '/');
- Filesystem::mount($storage2, array(), $defaultRoot . '_substorage');
+ Filesystem::mount($storage1, [], '/');
+ Filesystem::mount($storage2, [], $defaultRoot . '_substorage');
\OC_Hook::connect('OC_Filesystem', 'post_write', $this, 'dummyHook');
$subView = new View($defaultRoot . '_substorage');
@@ -710,8 +713,8 @@ class ViewTest extends \Test\TestCase {
$storage1 = $this->getTestStorage();
$storage2 = $this->getTestStorage();
$defaultRoot = Filesystem::getRoot();
- Filesystem::mount($storage1, array(), '/');
- Filesystem::mount($storage2, array(), $defaultRoot);
+ Filesystem::mount($storage1, [], '/');
+ Filesystem::mount($storage2, [], $defaultRoot);
\OC_Hook::connect('OC_Filesystem', 'post_create', $this, 'dummyHookCreate');
\OC_Hook::connect('OC_Filesystem', 'post_update', $this, 'dummyHookUpdate');
\OC_Hook::connect('OC_Filesystem', 'post_write', $this, 'dummyHookWrite');
@@ -741,7 +744,7 @@ class ViewTest extends \Test\TestCase {
*/
public function testResolvePath($expected, $pathToTest) {
$storage1 = $this->getTestStorage();
- Filesystem::mount($storage1, array(), '/');
+ Filesystem::mount($storage1, [], '/');
$view = new View('');
@@ -756,25 +759,25 @@ class ViewTest extends \Test\TestCase {
}
public function resolvePathTestProvider() {
- return array(
- array('foo.txt', 'foo.txt'),
- array('foo.txt', '/foo.txt'),
- array('folder', 'folder'),
- array('folder', '/folder'),
- array('folder', 'folder/'),
- array('folder', '/folder/'),
- array('folder/bar.txt', 'folder/bar.txt'),
- array('folder/bar.txt', '/folder/bar.txt'),
- array('', ''),
- array('', '/'),
- );
+ return [
+ ['foo.txt', 'foo.txt'],
+ ['foo.txt', '/foo.txt'],
+ ['folder', 'folder'],
+ ['folder', '/folder'],
+ ['folder', 'folder/'],
+ ['folder', '/folder/'],
+ ['folder/bar.txt', 'folder/bar.txt'],
+ ['folder/bar.txt', '/folder/bar.txt'],
+ ['', ''],
+ ['', '/'],
+ ];
}
public function testUTF8Names() {
- $names = array('虚', '和知しゃ和で', 'regular ascii', 'sɨˈrɪlɪk', 'ѨѬ', 'أنا أحب القراءة كثيرا');
+ $names = ['虚', '和知しゃ和で', 'regular ascii', 'sɨˈrɪlɪk', 'ѨѬ', 'أنا أحب القراءة كثيرا'];
- $storage = new Temporary(array());
- Filesystem::mount($storage, array(), '/');
+ $storage = new Temporary([]);
+ Filesystem::mount($storage, [], '/');
$rootView = new View('');
foreach ($names as $name) {
@@ -802,8 +805,8 @@ class ViewTest extends \Test\TestCase {
public function xtestLongPath() {
- $storage = new Temporary(array());
- Filesystem::mount($storage, array(), '/');
+ $storage = new Temporary([]);
+ Filesystem::mount($storage, [], '/');
$rootView = new View('');
@@ -851,9 +854,9 @@ class ViewTest extends \Test\TestCase {
}
public function testTouchNotSupported() {
- $storage = new TemporaryNoTouch(array());
+ $storage = new TemporaryNoTouch([]);
$scanner = $storage->getScanner();
- Filesystem::mount($storage, array(), '/test/');
+ Filesystem::mount($storage, [], '/test/');
$past = time() - 100;
$storage->file_put_contents('test', 'foobar');
$scanner->scan('');
@@ -868,13 +871,13 @@ class ViewTest extends \Test\TestCase {
}
public function testWatcherEtagCrossStorage() {
- $storage1 = new Temporary(array());
- $storage2 = new Temporary(array());
+ $storage1 = new Temporary([]);
+ $storage2 = new Temporary([]);
$scanner1 = $storage1->getScanner();
$scanner2 = $storage2->getScanner();
$storage1->mkdir('sub');
- Filesystem::mount($storage1, array(), '/test/');
- Filesystem::mount($storage2, array(), '/test/sub/storage');
+ Filesystem::mount($storage1, [], '/test/');
+ Filesystem::mount($storage2, [], '/test/sub/storage');
$past = time() - 100;
$storage2->file_put_contents('test.txt', 'foobar');
@@ -887,9 +890,9 @@ class ViewTest extends \Test\TestCase {
$oldFileInfo = $view->getFileInfo('/test/sub/storage/test.txt');
$oldFolderInfo = $view->getFileInfo('/test');
- $storage2->getCache()->update($oldFileInfo->getId(), array(
- 'storage_mtime' => $past
- ));
+ $storage2->getCache()->update($oldFileInfo->getId(), [
+ 'storage_mtime' => $past,
+ ]);
$oldEtag = $oldFolderInfo->getEtag();
@@ -908,9 +911,9 @@ class ViewTest extends \Test\TestCase {
}
public function testPartFileInfo() {
- $storage = new Temporary(array());
+ $storage = new Temporary([]);
$scanner = $storage->getScanner();
- Filesystem::mount($storage, array(), '/test/');
+ Filesystem::mount($storage, [], '/test/');
$storage->file_put_contents('test.part', 'foobar');
$scanner->scan('');
$view = new View('/test');
@@ -922,15 +925,15 @@ class ViewTest extends \Test\TestCase {
}
public function absolutePathProvider() {
- return array(
- array('/files/', ''),
- array('/files/0', '0'),
- array('/files/false', 'false'),
- array('/files/true', 'true'),
- array('/files/', '/'),
- array('/files/test', 'test'),
- array('/files/test', '/test'),
- );
+ return [
+ ['/files/', ''],
+ ['/files/0', '0'],
+ ['/files/false', 'false'],
+ ['/files/true', 'true'],
+ ['/files/', '/'],
+ ['/files/test', 'test'],
+ ['/files/test', '/test'],
+ ];
}
/**
@@ -959,81 +962,81 @@ class ViewTest extends \Test\TestCase {
}
public function relativePathProvider($missingRootExpectedPath) {
- return array(
+ return [
// No root - returns the path
- array('', '/files', '/files'),
- array('', '/files/', '/files/'),
+ ['', '/files', '/files'],
+ ['', '/files/', '/files/'],
// Root equals path - /
- array('/files/', '/files/', '/'),
- array('/files/', '/files', '/'),
- array('/files', '/files/', '/'),
- array('/files', '/files', '/'),
+ ['/files/', '/files/', '/'],
+ ['/files/', '/files', '/'],
+ ['/files', '/files/', '/'],
+ ['/files', '/files', '/'],
// False negatives: chroot fixes those by adding the leading slash.
// But setting them up with this root (instead of chroot($root))
// will fail them, although they should be the same.
// TODO init should be fixed, so it also adds the leading slash
- array('files/', '/files/', $missingRootExpectedPath),
- array('files', '/files/', $missingRootExpectedPath),
- array('files/', '/files', $missingRootExpectedPath),
- array('files', '/files', $missingRootExpectedPath),
+ ['files/', '/files/', $missingRootExpectedPath],
+ ['files', '/files/', $missingRootExpectedPath],
+ ['files/', '/files', $missingRootExpectedPath],
+ ['files', '/files', $missingRootExpectedPath],
// False negatives: Paths provided to the method should have a leading slash
// TODO input should be checked to have a leading slash
- array('/files/', 'files/', null),
- array('/files', 'files/', null),
- array('/files/', 'files', null),
- array('/files', 'files', null),
+ ['/files/', 'files/', null],
+ ['/files', 'files/', null],
+ ['/files/', 'files', null],
+ ['/files', 'files', null],
// with trailing slashes
- array('/files/', '/files/0', '0'),
- array('/files/', '/files/false', 'false'),
- array('/files/', '/files/true', 'true'),
- array('/files/', '/files/test', 'test'),
- array('/files/', '/files/test/foo', 'test/foo'),
+ ['/files/', '/files/0', '0'],
+ ['/files/', '/files/false', 'false'],
+ ['/files/', '/files/true', 'true'],
+ ['/files/', '/files/test', 'test'],
+ ['/files/', '/files/test/foo', 'test/foo'],
// without trailing slashes
// TODO false expectation: Should match "with trailing slashes"
- array('/files', '/files/0', '/0'),
- array('/files', '/files/false', '/false'),
- array('/files', '/files/true', '/true'),
- array('/files', '/files/test', '/test'),
- array('/files', '/files/test/foo', '/test/foo'),
+ ['/files', '/files/0', '/0'],
+ ['/files', '/files/false', '/false'],
+ ['/files', '/files/true', '/true'],
+ ['/files', '/files/test', '/test'],
+ ['/files', '/files/test/foo', '/test/foo'],
// leading slashes
- array('/files/', '/files_trashbin/', null),
- array('/files', '/files_trashbin/', null),
- array('/files/', '/files_trashbin', null),
- array('/files', '/files_trashbin', null),
+ ['/files/', '/files_trashbin/', null],
+ ['/files', '/files_trashbin/', null],
+ ['/files/', '/files_trashbin', null],
+ ['/files', '/files_trashbin', null],
// no leading slashes
- array('files/', 'files_trashbin/', null),
- array('files', 'files_trashbin/', null),
- array('files/', 'files_trashbin', null),
- array('files', 'files_trashbin', null),
+ ['files/', 'files_trashbin/', null],
+ ['files', 'files_trashbin/', null],
+ ['files/', 'files_trashbin', null],
+ ['files', 'files_trashbin', null],
// mixed leading slashes
- array('files/', '/files_trashbin/', null),
- array('/files/', 'files_trashbin/', null),
- array('files', '/files_trashbin/', null),
- array('/files', 'files_trashbin/', null),
- array('files/', '/files_trashbin', null),
- array('/files/', 'files_trashbin', null),
- array('files', '/files_trashbin', null),
- array('/files', 'files_trashbin', null),
-
- array('files', 'files_trashbin/test', null),
- array('/files', '/files_trashbin/test', null),
- array('/files', 'files_trashbin/test', null),
- );
+ ['files/', '/files_trashbin/', null],
+ ['/files/', 'files_trashbin/', null],
+ ['files', '/files_trashbin/', null],
+ ['/files', 'files_trashbin/', null],
+ ['files/', '/files_trashbin', null],
+ ['/files/', 'files_trashbin', null],
+ ['files', '/files_trashbin', null],
+ ['/files', 'files_trashbin', null],
+
+ ['files', 'files_trashbin/test', null],
+ ['/files', '/files_trashbin/test', null],
+ ['/files', 'files_trashbin/test', null],
+ ];
}
public function testFileView() {
- $storage = new Temporary(array());
+ $storage = new Temporary([]);
$scanner = $storage->getScanner();
$storage->file_put_contents('foo.txt', 'bar');
- Filesystem::mount($storage, array(), '/test/');
+ Filesystem::mount($storage, [], '/test/');
$scanner->scan('');
$view = new View('/test/foo.txt');
@@ -1059,9 +1062,9 @@ class ViewTest extends \Test\TestCase {
$longPath .= '/' . $folderName;
}
- $storage = new Temporary(array());
+ $storage = new Temporary([]);
$this->tempStorage = $storage; // for later hard cleanup
- Filesystem::mount($storage, array(), '/');
+ Filesystem::mount($storage, [], '/');
$rootView = new View('');
@@ -1074,64 +1077,64 @@ class ViewTest extends \Test\TestCase {
$longPath = 'md5';
}
- call_user_func(array($rootView, $operation), $longPath, $param0);
+ call_user_func([$rootView, $operation], $longPath, $param0);
}
public function tooLongPathDataProvider() {
- return array(
- array('getAbsolutePath'),
- array('getRelativePath'),
- array('getMountPoint'),
- array('resolvePath'),
- array('getLocalFile'),
- array('getLocalFolder'),
- array('mkdir'),
- array('rmdir'),
- array('opendir'),
- array('is_dir'),
- array('is_file'),
- array('stat'),
- array('filetype'),
- array('filesize'),
- array('readfile'),
- array('isCreatable'),
- array('isReadable'),
- array('isUpdatable'),
- array('isDeletable'),
- array('isSharable'),
- array('file_exists'),
- array('filemtime'),
- array('touch'),
- array('file_get_contents'),
- array('unlink'),
- array('deleteAll'),
- array('toTmpFile'),
- array('getMimeType'),
- array('free_space'),
- array('getFileInfo'),
- array('getDirectoryContent'),
- array('getOwner'),
- array('getETag'),
- array('file_put_contents', 'ipsum'),
- array('rename', '@0'),
- array('copy', '@0'),
- array('fopen', 'r'),
- array('fromTmpFile', '@0'),
- array('hash'),
- array('hasUpdated', 0),
- array('putFileInfo', array()),
- );
+ return [
+ ['getAbsolutePath'],
+ ['getRelativePath'],
+ ['getMountPoint'],
+ ['resolvePath'],
+ ['getLocalFile'],
+ ['getLocalFolder'],
+ ['mkdir'],
+ ['rmdir'],
+ ['opendir'],
+ ['is_dir'],
+ ['is_file'],
+ ['stat'],
+ ['filetype'],
+ ['filesize'],
+ ['readfile'],
+ ['isCreatable'],
+ ['isReadable'],
+ ['isUpdatable'],
+ ['isDeletable'],
+ ['isSharable'],
+ ['file_exists'],
+ ['filemtime'],
+ ['touch'],
+ ['file_get_contents'],
+ ['unlink'],
+ ['deleteAll'],
+ ['toTmpFile'],
+ ['getMimeType'],
+ ['free_space'],
+ ['getFileInfo'],
+ ['getDirectoryContent'],
+ ['getOwner'],
+ ['getETag'],
+ ['file_put_contents', 'ipsum'],
+ ['rename', '@0'],
+ ['copy', '@0'],
+ ['fopen', 'r'],
+ ['fromTmpFile', '@0'],
+ ['hash'],
+ ['hasUpdated', 0],
+ ['putFileInfo', []],
+ ];
}
public function testRenameCrossStoragePreserveMtime() {
- $storage1 = new Temporary(array());
- $storage2 = new Temporary(array());
+ $storage1 = new Temporary([]);
+ $storage2 = new Temporary([]);
$storage1->mkdir('sub');
$storage1->mkdir('foo');
$storage1->file_put_contents('foo.txt', 'asd');
$storage1->file_put_contents('foo/bar.txt', 'asd');
- Filesystem::mount($storage1, array(), '/test/');
- Filesystem::mount($storage2, array(), '/test/sub/storage');
+ Filesystem::mount($storage1, [], '/test/');
+ Filesystem::mount($storage2, [], '/test/sub/storage');
$view = new View('');
$time = time() - 200;
@@ -1157,7 +1160,7 @@ class ViewTest extends \Test\TestCase {
}
private function doTestCopyRenameFail($operation) {
- $storage1 = new Temporary(array());
+ $storage1 = new Temporary([]);
/** @var \PHPUnit_Framework_MockObject_MockObject|Temporary $storage2 */
$storage2 = $this->getMockBuilder(TemporaryNoCross::class)
->setConstructorArgs([[]])
@@ -1180,8 +1183,8 @@ class ViewTest extends \Test\TestCase {
$storage2->file_put_contents('existing.txt', '0123');
$storage1->getScanner()->scan('');
$storage2->getScanner()->scan('');
- Filesystem::mount($storage1, array(), '/test/');
- Filesystem::mount($storage2, array(), '/test/sub/storage');
+ Filesystem::mount($storage1, [], '/test/');
+ Filesystem::mount($storage2, [], '/test/sub/storage');
// move file
$view = new View('');
@@ -1212,8 +1215,8 @@ class ViewTest extends \Test\TestCase {
public function testDeleteFailKeepCache() {
/** @var Temporary|\PHPUnit_Framework_MockObject_MockObject $storage */
$storage = $this->getMockBuilder(Temporary::class)
- ->setConstructorArgs(array(array()))
- ->setMethods(array('unlink'))
+ ->setConstructorArgs([[]])
+ ->setMethods(['unlink'])
->getMock();
$storage->expects($this->once())
->method('unlink')
@@ -1222,7 +1225,7 @@ class ViewTest extends \Test\TestCase {
$cache = $storage->getCache();
$storage->file_put_contents('foo.txt', 'asd');
$scanner->scan('');
- Filesystem::mount($storage, array(), '/test/');
+ Filesystem::mount($storage, [], '/test/');
$view = new View('/test');
@@ -1248,14 +1251,14 @@ class ViewTest extends \Test\TestCase {
}
public function testRenameOverWrite() {
- $storage = new Temporary(array());
+ $storage = new Temporary([]);
$scanner = $storage->getScanner();
$storage->mkdir('sub');
$storage->mkdir('foo');
$storage->file_put_contents('foo.txt', 'asd');
$storage->file_put_contents('foo/bar.txt', 'asd');
$scanner->scan('');
- Filesystem::mount($storage, array(), '/test/');
+ Filesystem::mount($storage, [], '/test/');
$view = new View('');
$this->assertTrue($view->rename('/test/foo.txt', '/test/foo/bar.txt'));
}
@@ -1309,7 +1312,7 @@ class ViewTest extends \Test\TestCase {
$pathPrefix = str_replace('{folder}', 'files', $pathPrefix);
$view = new View($rootPath);
- $storage = new Temporary(array());
+ $storage = new Temporary([]);
Filesystem::mount($storage, [], '/');
$this->assertTrue($view->lockFile($pathPrefix . '/foo/bar', ILockingProvider::LOCK_EXCLUSIVE));
$view->lockFile($pathPrefix . '/foo/bar/asd', ILockingProvider::LOCK_SHARED);
@@ -1328,7 +1331,7 @@ class ViewTest extends \Test\TestCase {
$pathPrefix = str_replace('{folder}', 'files_encryption', $pathPrefix);
$view = new View($rootPath);
- $storage = new Temporary(array());
+ $storage = new Temporary([]);
Filesystem::mount($storage, [], '/');
$this->assertFalse($view->lockFile($pathPrefix . '/foo/bar', ILockingProvider::LOCK_EXCLUSIVE));
$this->assertFalse($view->lockFile($pathPrefix . '/foo/bar/asd', ILockingProvider::LOCK_SHARED));
@@ -1349,7 +1352,7 @@ class ViewTest extends \Test\TestCase {
$pathPrefix = str_replace('{folder}', 'files', $pathPrefix);
$view = new View($rootPath);
- $storage = new Temporary(array());
+ $storage = new Temporary([]);
Filesystem::mount($storage, [], '/');
$this->assertTrue($view->lockFile($pathPrefix . '/foo/bar', ILockingProvider::LOCK_SHARED));
$view->lockFile($pathPrefix . '/foo/bar', ILockingProvider::LOCK_EXCLUSIVE);
@@ -1368,7 +1371,7 @@ class ViewTest extends \Test\TestCase {
$pathPrefix = str_replace('{folder}', 'files_encryption', $pathPrefix);
$view = new View($rootPath);
- $storage = new Temporary(array());
+ $storage = new Temporary([]);
Filesystem::mount($storage, [], '/');
$this->assertFalse($view->lockFile($pathPrefix . '/foo/bar', ILockingProvider::LOCK_SHARED));
$this->assertFalse($view->lockFile($pathPrefix . '/foo/bar', ILockingProvider::LOCK_EXCLUSIVE));
@@ -1516,7 +1519,7 @@ class ViewTest extends \Test\TestCase {
public function testChangeLock() {
$view = new View('/testuser/files/');
- $storage = new Temporary(array());
+ $storage = new Temporary([]);
Filesystem::mount($storage, [], '/');
$view->lockFile('/test/sub', ILockingProvider::LOCK_SHARED);
@@ -1544,7 +1547,7 @@ class ViewTest extends \Test\TestCase {
['/foo', '/files/foo', true],
['/foo', 'filesfoo', false],
['', '/foo/files', true],
- ['', '/foo/files/bar.txt', true]
+ ['', '/foo/files/bar.txt', true],
];
}
@@ -1828,7 +1831,7 @@ class ViewTest extends \Test\TestCase {
->setMethods([$operation])
->getMock();
- Filesystem::mount($storage, array(), $this->user . '/');
+ Filesystem::mount($storage, [], $this->user . '/');
// work directly on disk because mkdir might be mocked
$realPath = $storage->getSourcePath('');
@@ -1852,7 +1855,7 @@ class ViewTest extends \Test\TestCase {
$this->connectMockHooks($hookType, $view, $lockedPath, $lockTypePre, $lockTypePost);
// do operation
- call_user_func_array(array($view, $operation), $operationArgs);
+ call_user_func_array([$view, $operation], $operationArgs);
if ($hookType !== null) {
$this->assertEquals($expectedLockBefore, $lockTypePre, 'File locked properly during pre-hook');
@@ -1878,7 +1881,7 @@ class ViewTest extends \Test\TestCase {
->setMethods(['fopen'])
->getMock();
- Filesystem::mount($storage, array(), $this->user . '/');
+ Filesystem::mount($storage, [], $this->user . '/');
$storage->mkdir('files');
$storage->expects($this->once())
@@ -1917,7 +1920,7 @@ class ViewTest extends \Test\TestCase {
->setMethods(['fopen'])
->getMock();
- Filesystem::mount($storage, array(), $this->user . '/');
+ Filesystem::mount($storage, [], $this->user . '/');
$storage->mkdir('files');
$storage->expects($this->once())
@@ -1972,7 +1975,7 @@ class ViewTest extends \Test\TestCase {
->setMethods([$operation])
->getMock();
- Filesystem::mount($storage, array(), $this->user . '/');
+ Filesystem::mount($storage, [], $this->user . '/');
// work directly on disk because mkdir might be mocked
$realPath = $storage->getSourcePath('');
@@ -1991,7 +1994,7 @@ class ViewTest extends \Test\TestCase {
$thrown = false;
try {
- call_user_func_array(array($view, $operation), $operationArgs);
+ call_user_func_array([$view, $operation], $operationArgs);
} catch (\Exception $e) {
$thrown = true;
$this->assertEquals('Simulated exception', $e->getMessage());
@@ -2005,7 +2008,7 @@ class ViewTest extends \Test\TestCase {
$storage = new Temporary([]);
- Filesystem::mount($storage, array(), $this->user . '/');
+ Filesystem::mount($storage, [], $this->user . '/');
$storage->mkdir('files');
$storage->mkdir('files/dir');
@@ -2054,7 +2057,7 @@ class ViewTest extends \Test\TestCase {
->setMethods([$operation])
->getMock();
- Filesystem::mount($storage, array(), $this->user . '/');
+ Filesystem::mount($storage, [], $this->user . '/');
$storage->mkdir('files');
Util::connectHook(
@@ -2064,7 +2067,7 @@ class ViewTest extends \Test\TestCase {
'cancellingCallback'
);
- call_user_func_array(array($view, $operation), $operationArgs);
+ call_user_func_array([$view, $operation], $operationArgs);
$this->assertNull($this->getFileLockType($view, $path), 'File got unlocked after exception');
}
@@ -2100,7 +2103,7 @@ class ViewTest extends \Test\TestCase {
$sourcePath = 'original.txt';
$targetPath = 'target.txt';
- Filesystem::mount($storage, array(), $this->user . '/');
+ Filesystem::mount($storage, [], $this->user . '/');
$storage->mkdir('files');
$view->file_put_contents($sourcePath, 'meh');
@@ -2152,7 +2155,7 @@ class ViewTest extends \Test\TestCase {
$sourcePath = 'original.txt';
$targetPath = 'target.txt';
- Filesystem::mount($storage, array(), $this->user . '/');
+ Filesystem::mount($storage, [], $this->user . '/');
$storage->mkdir('files');
$view->file_put_contents($sourcePath, 'meh');
@@ -2279,8 +2282,8 @@ class ViewTest extends \Test\TestCase {
$sourcePath = 'original.txt';
$targetPath = 'substorage/target.txt';
- Filesystem::mount($storage, array(), $this->user . '/');
- Filesystem::mount($storage2, array(), $this->user . '/files/substorage');
+ Filesystem::mount($storage, [], $this->user . '/');
+ Filesystem::mount($storage2, [], $this->user . '/files/substorage');
$storage->mkdir('files');
$view->file_put_contents($sourcePath, 'meh');
@@ -2513,7 +2516,7 @@ class ViewTest extends \Test\TestCase {
public function testGetDirectoryContentMimeFilter($filter, $expected) {
$storage1 = new Temporary();
$root = self::getUniqueID('/');
- Filesystem::mount($storage1, array(), $root . '/');
+ Filesystem::mount($storage1, [], $root . '/');
$view = new View($root);
$view->file_put_contents('test1.txt', 'asd');
@@ -2532,10 +2535,10 @@ class ViewTest extends \Test\TestCase {
}
public function testFilePutContentsClearsChecksum() {
- $storage = new Temporary(array());
+ $storage = new Temporary([]);
$scanner = $storage->getScanner();
$storage->file_put_contents('foo.txt', 'bar');
- Filesystem::mount($storage, array(), '/test/');
+ Filesystem::mount($storage, [], '/test/');
$scanner->scan('');
$view = new View('/test/foo.txt');
@@ -2552,11 +2555,11 @@ class ViewTest extends \Test\TestCase {
}
public function testDeleteGhostFile() {
- $storage = new Temporary(array());
+ $storage = new Temporary([]);
$scanner = $storage->getScanner();
$cache = $storage->getCache();
$storage->file_put_contents('foo.txt', 'bar');
- Filesystem::mount($storage, array(), '/test/');
+ Filesystem::mount($storage, [], '/test/');
$scanner->scan('');
$storage->unlink('foo.txt');
@@ -2575,12 +2578,12 @@ class ViewTest extends \Test\TestCase {
}
public function testDeleteGhostFolder() {
- $storage = new Temporary(array());
+ $storage = new Temporary([]);
$scanner = $storage->getScanner();
$cache = $storage->getCache();
$storage->mkdir('foo');
$storage->file_put_contents('foo/foo.txt', 'bar');
- Filesystem::mount($storage, array(), '/test/');
+ Filesystem::mount($storage, [], '/test/');
$scanner->scan('');
$storage->rmdir('foo');
@@ -2669,4 +2672,24 @@ class ViewTest extends \Test\TestCase {
->willReturn(true);
$this->assertFalse(self::invokePrivate($view, 'createParentDirectories', ['/file.txt/folder/structure']));
}
+
+ public function testCacheExtension() {
+ $storage = new Temporary([]);
+ $scanner = $storage->getScanner();
+ $storage->file_put_contents('foo.txt', 'bar');
+ $scanner->scan('');
+
+ Filesystem::mount($storage, [], '/test/');
+ $view = new View('/test');
+
+ $info = $view->getFileInfo('/foo.txt');
+ $this->assertEquals(0, $info->getUploadTime());
+ $this->assertEquals(0, $info->getCreationTime());
+
+ $view->putFileInfo('/foo.txt', ['upload_time' => 25]);
+
+ $info = $view->getFileInfo('/foo.txt');
+ $this->assertEquals(25, $info->getUploadTime());
+ $this->assertEquals(0, $info->getCreationTime());
+ }
}
diff --git a/tests/lib/HelperStorageTest.php b/tests/lib/HelperStorageTest.php
index d42c43c5ab8..dacd73a4f01 100644
--- a/tests/lib/HelperStorageTest.php
+++ b/tests/lib/HelperStorageTest.php
@@ -26,6 +26,7 @@ class HelperStorageTest extends \Test\TestCase {
parent::setUp();
$this->user = $this->getUniqueID('user_');
+ \OC_User::useBackend('dummy');
\OC::$server->getUserManager()->createUser($this->user, $this->user);
$this->storage = \OC\Files\Filesystem::getStorage('/');