big: recurse all mountpoints in timeline path

pull/221/head
Varun Patil 2022-11-15 07:12:27 -08:00
parent 5f59183726
commit 34340de5f1
2 changed files with 51 additions and 28 deletions

View File

@ -8,14 +8,14 @@ use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Folder; use OCP\Files\Folder;
use OCP\IDBConnection; use OCP\IDBConnection;
const CTE_FOLDERS = // CTE to get all folders recursively in the given top folder const CTE_FOLDERS = // CTE to get all folders recursively in the given top folders excluding archive
'WITH RECURSIVE *PREFIX*cte_folders(fileid) AS ( 'WITH RECURSIVE *PREFIX*cte_folders(fileid) AS (
SELECT SELECT
f.fileid f.fileid
FROM FROM
*PREFIX*filecache f *PREFIX*filecache f
WHERE WHERE
f.fileid = :topFolderId f.fileid IN (:topFolderIds)
UNION ALL UNION ALL
SELECT SELECT
f.fileid f.fileid
@ -24,10 +24,43 @@ const CTE_FOLDERS = // CTE to get all folders recursively in the given top folde
INNER JOIN *PREFIX*cte_folders c INNER JOIN *PREFIX*cte_folders c
ON (f.parent = c.fileid ON (f.parent = c.fileid
AND f.mimetype = (SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = \'httpd/unix-directory\') AND f.mimetype = (SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = \'httpd/unix-directory\')
AND f.fileid <> :excludedFolderId AND f.name <> \'.archive\'
) )
)'; )';
const CTE_FOLDERS_ARCHIVE = // CTE to get all archive folders recursively in the given top folders
'WITH RECURSIVE *PREFIX*cte_folders_all(fileid, name) AS (
SELECT
f.fileid, f.name
FROM
*PREFIX*filecache f
WHERE
f.fileid IN (:topFolderIds)
UNION ALL
SELECT
f.fileid, f.name
FROM
*PREFIX*filecache f
INNER JOIN *PREFIX*cte_folders_all c
ON (f.parent = c.fileid
AND f.mimetype = (SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = \'httpd/unix-directory\')
)
), *PREFIX*cte_folders(fileid) AS (
SELECT
f.fileid
FROM
*PREFIX*cte_folders_all f
WHERE
f.name = \'.archive\'
UNION ALL
SELECT
f.fileid
FROM
*PREFIX*filecache f
INNER JOIN *PREFIX*cte_folders c
ON (f.parent = c.fileid)
)';
trait TimelineQueryDays trait TimelineQueryDays
{ {
protected IDBConnection $connection; protected IDBConnection $connection;
@ -231,9 +264,12 @@ trait TimelineQueryDays
$params = $query->getParameters(); $params = $query->getParameters();
$types = $query->getParameterTypes(); $types = $query->getParameterTypes();
// Get SQL
$CTE_SQL = $params['cteFoldersArchive'] ? CTE_FOLDERS_ARCHIVE : CTE_FOLDERS;
// Add WITH clause if needed // Add WITH clause if needed
if (false !== strpos($sql, 'cte_folders')) { if (false !== strpos($sql, 'cte_folders')) {
$sql = CTE_FOLDERS.' '.$sql; $sql = $CTE_SQL.' '.$sql;
} }
return $this->connection->executeQuery($sql, $params, $types); return $this->connection->executeQuery($sql, $params, $types);
@ -247,31 +283,16 @@ trait TimelineQueryDays
Folder &$folder, Folder &$folder,
bool $archive bool $archive
) { ) {
// Query parameters, set at the end // Get storages recursively
$topFolderId = $folder->getId(); $topFolderIds = [$folder->getId()];
$excludedFolderId = -1; $mounts = \OC\Files\Filesystem::getMountManager()->findIn($folder->getPath());
foreach ($mounts as &$mount) {
/** @var Folder Archive folder if it exists */ $topFolderIds[] = $mount->getStorageRootId();
$archiveFolder = null;
try {
$archiveFolder = $folder->get('.archive/');
} catch (\OCP\Files\NotFoundException $e) {
}
if (!$archive) {
// Exclude archive folder
if ($archiveFolder) {
$excludedFolderId = $archiveFolder->getId();
}
} else {
// Only include archive folder
$topFolderId = $archiveFolder ? $archiveFolder->getId() : -1;
} }
// Add query parameters // Add query parameters
$query->setParameter('topFolderId', $topFolderId, IQueryBuilder::PARAM_INT); $query->setParameter('topFolderIds', $topFolderIds, IQueryBuilder::PARAM_INT_ARRAY);
$query->setParameter('excludedFolderId', $excludedFolderId, IQueryBuilder::PARAM_INT); $query->setParameter('cteFoldersArchive', $archive, IQueryBuilder::PARAM_BOOL);
} }
/** /**

View File

@ -91,10 +91,11 @@ export default class Settings extends Mixins(UserConfig, GlobalMixin) {
} }
async chooseTimelinePath() { async chooseTimelinePath() {
const newPath = await this.chooseFolder( let newPath = await this.chooseFolder(
this.t("memories", "Choose the root of your timeline"), this.t("memories", "Choose the root of your timeline"),
this.config_timelinePath this.config_timelinePath
); );
if (newPath === "") newPath = "/";
if (newPath !== this.config_timelinePath) { if (newPath !== this.config_timelinePath) {
this.config_timelinePath = newPath; this.config_timelinePath = newPath;
await this.updateSetting("timelinePath"); await this.updateSetting("timelinePath");
@ -102,10 +103,11 @@ export default class Settings extends Mixins(UserConfig, GlobalMixin) {
} }
async chooseFoldersPath() { async chooseFoldersPath() {
const newPath = await this.chooseFolder( let newPath = await this.chooseFolder(
this.t("memories", "Choose the root for the folders view"), this.t("memories", "Choose the root for the folders view"),
this.config_foldersPath this.config_foldersPath
); );
if (newPath === "") newPath = "/";
if (newPath !== this.config_foldersPath) { if (newPath !== this.config_foldersPath) {
this.config_foldersPath = newPath; this.config_foldersPath = newPath;
await this.updateSetting("foldersPath"); await this.updateSetting("foldersPath");