From 5439469b687478eb5626f69adce3e38060fcd99e Mon Sep 17 00:00:00 2001
From: Robin Appelman <robin@icewind.nl>
Date: Fri, 14 Feb 2020 22:07:09 +0100
Subject: optimize getMetaData for local storage

Signed-off-by: Robin Appelman <robin@icewind.nl>
---
 lib/private/Files/Storage/Local.php | 63 +++++++++++++++++++++++++++++++++----
 1 file changed, 57 insertions(+), 6 deletions(-)

(limited to 'lib/private/Files/Storage/Local.php')

diff --git a/lib/private/Files/Storage/Local.php b/lib/private/Files/Storage/Local.php
index a85cf1a734a..fbb84418e2e 100644
--- a/lib/private/Files/Storage/Local.php
+++ b/lib/private/Files/Storage/Local.php
@@ -43,6 +43,7 @@ namespace OC\Files\Storage;
 
 use OC\Files\Filesystem;
 use OC\Files\Storage\Wrapper\Jail;
+use OCP\Constants;
 use OCP\Files\ForbiddenException;
 use OCP\Files\Storage\IStorage;
 use OCP\ILogger;
@@ -111,9 +112,9 @@ class Local extends \OC\Files\Storage\Common {
 				if (in_array($file->getBasename(), ['.', '..'])) {
 					$it->next();
 					continue;
-				} elseif ($file->isDir()) {
+				} else if ($file->isDir()) {
 					rmdir($file->getPathname());
-				} elseif ($file->isFile() || $file->isLink()) {
+				} else if ($file->isFile() || $file->isLink()) {
 					unlink($file->getPathname());
 				}
 				$it->next();
@@ -151,6 +152,54 @@ class Local extends \OC\Files\Storage\Common {
 		return $statResult;
 	}
 
+	/**
+	 * @inheritdoc
+	 */
+	public function getMetaData($path) {
+		$fullPath = $this->getSourcePath($path);
+		$stat = @stat($fullPath);
+		if (!$stat) {
+			return null;
+		}
+
+		$permissions = Constants::PERMISSION_SHARE;
+		$statPermissions = $stat['mode'];
+		$isDir = ($statPermissions & 0x4000) === 0x4000;
+		if ($statPermissions & 0x0100) {
+			$permissions += Constants::PERMISSION_READ;
+		}
+		if ($statPermissions & 0x0080) {
+			$permissions += Constants::PERMISSION_UPDATE;
+			if ($isDir) {
+				$permissions += Constants::PERMISSION_CREATE;
+			}
+		}
+
+		if (!($path === '' || $path === '/')) { // deletable depends on the parents unix permissions
+			$parent = dirname($fullPath);
+			if (is_writable($parent)) {
+				$permissions += Constants::PERMISSION_DELETE;
+			}
+		}
+
+		$data = [];
+		$data['mimetype'] = $isDir ? 'httpd/unix-directory' : \OC::$server->getMimeTypeDetector()->detectPath($path);
+		$data['mtime'] = $stat['mtime'];
+		if ($data['mtime'] === false) {
+			$data['mtime'] = time();
+		}
+		if ($isDir) {
+			$data['size'] = -1; //unknown
+		} else {
+			$data['size'] = $stat['size'];
+		}
+		$data['etag'] = $this->calculateEtag($path, $stat);
+		$data['storage_mtime'] = $data['mtime'];
+		$data['permissions'] = $permissions;
+
+		return $data;
+	}
+
 	public function filetype($path) {
 		$filetype = filetype($this->getSourcePath($path));
 		if ($filetype == 'link') {
@@ -424,9 +473,13 @@ class Local extends \OC\Files\Storage\Common {
 	 * @return string
 	 */
 	public function getETag($path) {
-		if ($this->is_file($path)) {
-			$stat = $this->stat($path);
+		return $this->calculateEtag($path, $this->stat($path));
+	}
 
+	private function calculateEtag(string $path, array $stat): string {
+		if ($stat['mode'] & 0x4000) { // is_dir
+			return parent::getETag($path);
+		} else {
 			if ($stat === false) {
 				return md5('');
 			}
@@ -446,8 +499,6 @@ class Local extends \OC\Files\Storage\Common {
 			}
 
 			return md5($toHash);
-		} else {
-			return parent::getETag($path);
 		}
 	}
 
-- 
cgit v1.2.3