diff --git a/lib/private/Preview/Db/PreviewMapper.php b/lib/private/Preview/Db/PreviewMapper.php index 9c50eddf7aad9..d747840d033df 100644 --- a/lib/private/Preview/Db/PreviewMapper.php +++ b/lib/private/Preview/Db/PreviewMapper.php @@ -11,6 +11,7 @@ use DateInterval; use DateTimeImmutable; +use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\Entity; use OCP\AppFramework\Db\QBMapper; use OCP\DB\Exception; @@ -235,4 +236,19 @@ public function getPreviewsForMimeTypes(array $mimeTypes): \Generator { )); return $this->yieldEntities($qb); } + + public function getPreviewForSpecification(array $parameters): ?Preview { + $qb = $this->db->getQueryBuilder(); + $this->joinLocation($qb); + + foreach ($parameters as $key => $value) { + $qb->andWhere($qb->expr()->eq($key, $qb->createNamedParameter($value))); + } + + try { + return $this->findEntity($qb); + } catch (DoesNotExistException) { + return null; + } + } } diff --git a/lib/private/Preview/Generator.php b/lib/private/Preview/Generator.php index f0ef8125e4931..dbe23f6ee87a2 100644 --- a/lib/private/Preview/Generator.php +++ b/lib/private/Preview/Generator.php @@ -587,6 +587,30 @@ public function savePreview(Preview $previewEntry, IImage $preview): Preview { } $previewEntry->setSize($size); $previewEntry->generateId(); - return $this->previewMapper->insert($previewEntry); + try { + return $this->previewMapper->insert($previewEntry); + } catch (DBException $e) { + if ($e->getReason() !== DBException::REASON_UNIQUE_CONSTRAINT_VIOLATION) { + throw $e; + } + + $this->storageFactory->deletePreview($previewEntry); + + $this->logger->debug("Generating a preview but one already exists.", ['exception' => $e]); + + $preview = $this->previewMapper->getPreviewForSpecification([ + 'file_id' => $previewEntry->getFileId(), + 'width' => $previewEntry->getWidth(), + 'height' => $previewEntry->getHeight(), + 'mimetype_id' => $previewEntry->getMimetypeId(), + 'cropped' => $previewEntry->isCropped(), + 'version_id' => $previewEntry->getVersion() ?? '-1', + ]); + + if ($preview === null) { + throw new \RuntimeException('Unable to save a preview because it already exists but fetching it again yield nothing'); + } + return $preview; + } } }