From 81e103074ea6ce9e7035734bc527ab582dbca89f Mon Sep 17 00:00:00 2001
From: Robin Appelman <robin@icewind.nl>
Date: Fri, 22 Jul 2016 13:58:53 +0200
Subject: [PATCH] use limit instead of since when listing recent files

---
 apps/files/lib/Controller/ApiController.php |  3 +-
 lib/private/Files/Node/Folder.php           | 49 +++------------------
 lib/private/Files/Node/LazyRoot.php         |  2 +-
 lib/public/Files/Folder.php                 |  5 ++-
 tests/lib/Files/Node/FolderTest.php         | 13 +++---
 5 files changed, 18 insertions(+), 54 deletions(-)

diff --git a/apps/files/lib/Controller/ApiController.php b/apps/files/lib/Controller/ApiController.php
index 8adc73a0a45..7ce83bfca15 100644
--- a/apps/files/lib/Controller/ApiController.php
+++ b/apps/files/lib/Controller/ApiController.php
@@ -198,8 +198,7 @@ class ApiController extends Controller {
 	 * @return DataResponse
 	 */
 	public function getRecentFiles() {
-		$since = time() - (60 * 60 * 24 * 7);//1 week
-		$nodes = $this->userFolder->getRecent($since);
+		$nodes = $this->userFolder->getRecent(100);
 		$files = $this->formatNodes($nodes);
 		return new DataResponse(['files' => $files]);
 	}
diff --git a/lib/private/Files/Node/Folder.php b/lib/private/Files/Node/Folder.php
index 7746757c2a5..e67e4817e2a 100644
--- a/lib/private/Files/Node/Folder.php
+++ b/lib/private/Files/Node/Folder.php
@@ -363,10 +363,11 @@ class Folder extends Node implements \OCP\Files\Folder {
 	}
 
 	/**
-	 * @param int $since
+	 * @param int $limit
+	 * @param int $offset
 	 * @return \OCP\Files\Node[]
 	 */
-	public function getRecent($since) {
+	public function getRecent($limit, $offset = 0) {
 		$mimetypeLoader = \OC::$server->getMimeTypeLoader();
 		$mounts = $this->root->getMountsIn($this->path);
 		$mounts[] = $this->getMountPoint();
@@ -387,55 +388,19 @@ class Folder extends Node implements \OCP\Files\Folder {
 		$query = $builder
 			->select('f.*')
 			->from('filecache', 'f')
-			->where($builder->expr()->gt('f.storage_mtime', $builder->createNamedParameter($since, IQueryBuilder::PARAM_INT)))
 			->andWhere($builder->expr()->in('f.storage', $builder->createNamedParameter($storageIds, IQueryBuilder::PARAM_INT_ARRAY)))
 			->andWhere($builder->expr()->orX(
 			// handle non empty folders separate
 				$builder->expr()->neq('f.mimetype', $builder->createNamedParameter($folderMimetype, IQueryBuilder::PARAM_INT)),
 				$builder->expr()->eq('f.size', new Literal(0))
 			))
-			->orderBy('f.mtime', 'DESC');
+			->orderBy('f.mtime', 'DESC')
+			->setMaxResults($limit)
+			->setFirstResult($offset);
 
 		$result = $query->execute()->fetchAll();
 
-		// select folders with their mtime being the mtime of the oldest file in the folder
-		// this way we still show new folders but dont bumb the folder every time a file in it is changed
-		$builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
-		$query = $builder
-			->select('p.fileid', 'p.storage', 'p.mimetype', 'p.mimepart', 'p.size', 'p.path', 'p.etag', 'f1.storage_mtime', 'f1.mtime', 'p.permissions')
-			->from('filecache', 'f1')
-			->leftJoin('f1', 'filecache', 'f2', $builder->expr()->andX( // find the f1 with lowest mtime in the folder
-				$builder->expr()->eq('f1.parent', 'f2.parent'),
-				$builder->expr()->gt('f1.storage_mtime', 'f2.storage_mtime')
-			))
-			->innerJoin('f1', 'filecache', 'p', $builder->expr()->eq('f1.parent', 'p.fileid'))
-			->where($builder->expr()->isNull('f2.fileid'))
-			->andWhere($builder->expr()->gt('f1.storage_mtime', $builder->createNamedParameter($since, IQueryBuilder::PARAM_INT)))
-			->andWhere($builder->expr()->in('f1.storage', $builder->createNamedParameter($storageIds, IQueryBuilder::PARAM_INT_ARRAY)))
-			->andWhere($builder->expr()->neq('f1.size', new Literal(0)))
-			->orderBy('f1.storage_mtime', 'DESC');
-
-		$folderResults = $query->execute()->fetchAll();
-
-		$found = []; // we sometimes get duplicate folders
-		$folderResults = array_filter($folderResults, function ($item) use (&$found) {
-			$isFound = isset($found[$item['fileid']]);
-			$found[$item['fileid']] = true;
-			return !$isFound;
-		});
-
-		$result = array_merge($folderResults, $result);
-
-		usort($result, function ($a, $b) use ($folderMimetype) {
-			$diff = $b['mtime'] - $a['mtime'];
-			if ($diff === 0) {
-				return $a['mimetype'] === $folderMimetype ? -1 : 1;
-			} else {
-				return $diff;
-			}
-		});
-
-		$files = array_filter(array_map(function (array $entry) use  ($mountMap, $mimetypeLoader) {
+		$files = array_filter(array_map(function (array $entry) use ($mountMap, $mimetypeLoader) {
 			$mount = $mountMap[$entry['storage']];
 			$entry['internalPath'] = $entry['path'];
 			$entry['mimetype'] = $mimetypeLoader->getMimetypeById($entry['mimetype']);
diff --git a/lib/private/Files/Node/LazyRoot.php b/lib/private/Files/Node/LazyRoot.php
index adc41153313..317b8144653 100644
--- a/lib/private/Files/Node/LazyRoot.php
+++ b/lib/private/Files/Node/LazyRoot.php
@@ -474,7 +474,7 @@ class LazyRoot implements IRootFolder {
 	/**
 	 * @inheritDoc
 	 */
-	public function getRecent($type) {
+	public function getRecent($limit, $offset = 0) {
 		return $this->__call(__FUNCTION__, func_get_args());
 	}
 }
diff --git a/lib/public/Files/Folder.php b/lib/public/Files/Folder.php
index b6686732f42..8f8576d8503 100644
--- a/lib/public/Files/Folder.php
+++ b/lib/public/Files/Folder.php
@@ -177,9 +177,10 @@ interface Folder extends Node {
 	public function getNonExistingName($name);
 
 	/**
-	 * @param int $since
+	 * @param int $limit
+	 * @param int $offset
 	 * @return \OCP\Files\Node[]
 	 * @since 9.1.0
 	 */
-	public function getRecent($since);
+	public function getRecent($limit, $offset = 0);
 }
diff --git a/tests/lib/Files/Node/FolderTest.php b/tests/lib/Files/Node/FolderTest.php
index eef78e7d428..18acfcae1fa 100644
--- a/tests/lib/Files/Node/FolderTest.php
+++ b/tests/lib/Files/Node/FolderTest.php
@@ -836,7 +836,7 @@ class FolderTest extends \Test\TestCase {
 			'mimetype' => 'text/plain',
 			'size' => 3
 		]);
-		$cache->put('bar/foo/toold.txt', [
+		$id3 = $cache->put('bar/foo/older.txt', [
 			'storage_mtime' => $baseTime - 600,
 			'mtime' => $baseTime - 600,
 			'mimetype' => 'text/plain',
@@ -846,11 +846,11 @@ class FolderTest extends \Test\TestCase {
 		$node = new \OC\Files\Node\Folder($root, $view, $folderPath, $folderInfo);
 
 
-		$nodes = $node->getRecent($baseTime - 500);
+		$nodes = $node->getRecent(5);
 		$ids = array_map(function (Node $node) {
 			return (int)$node->getId();
 		}, $nodes);
-		$this->assertEquals([$id1, $id2], $ids);
+		$this->assertEquals([$id1, $id2, $id3], $ids);
 	}
 
 	public function testRecentFolder() {
@@ -900,14 +900,13 @@ class FolderTest extends \Test\TestCase {
 		$node = new \OC\Files\Node\Folder($root, $view, $folderPath, $folderInfo);
 
 
-		$nodes = $node->getRecent($baseTime - 500);
+		$nodes = $node->getRecent(5);
 		$ids = array_map(function (Node $node) {
 			return (int)$node->getId();
 		}, $nodes);
-		$this->assertEquals([$id2, $id1, $id3], $ids);// sort folders before files with the same mtime, folders get the lowest child mtime
+		$this->assertEquals([$id2, $id3], $ids);
 		$this->assertEquals($baseTime, $nodes[0]->getMTime());
 		$this->assertEquals($baseTime - 100, $nodes[1]->getMTime());
-		$this->assertEquals($baseTime - 100, $nodes[2]->getMTime());
 	}
 
 	public function testRecentJail() {
@@ -952,7 +951,7 @@ class FolderTest extends \Test\TestCase {
 
 		$node = new \OC\Files\Node\Folder($root, $view, $folderPath, $folderInfo);
 
-		$nodes = $node->getRecent($baseTime - 500);
+		$nodes = $node->getRecent(5);
 		$ids = array_map(function (Node $node) {
 			return (int)$node->getId();
 		}, $nodes);
-- 
GitLab