setTimeSensitivity(self::TIME_INSENSITIVE); $this->setInterval(24 * 60 * 60); $this->previewRootPath = 'appdata_' . $this->config->getSystemValueString('instanceid') . '/preview/'; } #[Override] protected function run(mixed $argument): void { if ($this->appConfig->getValueBool('core', 'previewMovedDone')) { return; } $startTime = time(); while (true) { $qb = $this->connection->getQueryBuilder(); $qb->select('path') ->from('filecache') // Hierarchical preview folder structure ->where($qb->expr()->like('path', $qb->createNamedParameter($this->previewRootPath . '%/%/%/%/%/%/%/%/%'))) // Legacy flat preview folder structure ->orWhere($qb->expr()->like('path', $qb->createNamedParameter($this->previewRootPath . '%/%.%'))) ->hintShardKey('storage', $this->rootFolder->getMountPoint()->getNumericStorageId()) ->setMaxResults(100); $result = $qb->executeQuery(); $foundPreviews = $this->processQueryResult($result); if (!$foundPreviews) { break; } // Stop if execution time is more than one hour. if (time() - $startTime > 3600) { return; } } $this->appConfig->setValueBool('core', 'previewMovedDone', true); } private function processQueryResult(IResult $result): bool { $foundPreview = false; $fileIds = []; $flatFileIds = []; while ($row = $result->fetch()) { $pathSplit = explode('/', $row['path']); assert(count($pathSplit) >= 2); $fileId = (int)$pathSplit[count($pathSplit) - 2]; if (count($pathSplit) === 11) { // Hierarchical structure if (!in_array($fileId, $fileIds)) { $fileIds[] = $fileId; } } else { // Flat structure if (!in_array($fileId, $flatFileIds)) { $flatFileIds[] = $fileId; } } $foundPreview = true; } foreach ($fileIds as $fileId) { $this->migrationService->migrateFileId($fileId, flatPath: false); } foreach ($flatFileIds as $fileId) { $this->migrationService->migrateFileId($fileId, flatPath: true); } return $foundPreview; } }