Skip to content

Commit c69b7ff

Browse files
committed
fix(preview): Handle unique constraints violation exception
Delete the preview from storage and fetch the actual one from the DB. This should not happen often. Signed-off-by: Carl Schwan <carl@carlschwan.eu>
1 parent 6de8760 commit c69b7ff

2 files changed

Lines changed: 41 additions & 1 deletion

File tree

lib/private/Preview/Db/PreviewMapper.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
namespace OC\Preview\Db;
1111

12+
use OCP\AppFramework\Db\DoesNotExistException;
1213
use OCP\AppFramework\Db\Entity;
1314
use OCP\AppFramework\Db\QBMapper;
1415
use OCP\DB\Exception;
@@ -227,4 +228,19 @@ public function getPreviewsForMimeTypes(array $mimeTypes): \Generator {
227228
));
228229
return $this->yieldEntities($qb);
229230
}
231+
232+
public function getPreviewForSpecification(array $parameters): ?Preview {
233+
$qb = $this->db->getQueryBuilder();
234+
$this->joinLocation($qb);
235+
236+
foreach ($parameters as $key => $value) {
237+
$qb->andWhere($qb->expr()->eq($key, $qb->createNamedParameter($value)));
238+
}
239+
240+
try {
241+
return $this->findEntity($qb);
242+
} catch (DoesNotExistException) {
243+
return null;
244+
}
245+
}
230246
}

lib/private/Preview/Generator.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,30 @@ public function savePreview(Preview $previewEntry, IImage $preview): Preview {
590590
}
591591
$previewEntry->setSize($size);
592592
$previewEntry->generateId();
593-
return $this->previewMapper->insert($previewEntry);
593+
try {
594+
return $this->previewMapper->insert($previewEntry);
595+
} catch (DBException $e) {
596+
if ($e->getReason() !== DBException::REASON_UNIQUE_CONSTRAINT_VIOLATION) {
597+
throw $e;
598+
}
599+
600+
$this->storageFactory->deletePreview($previewEntry);
601+
602+
$this->logger->debug('Generating a preview but one already exists.', ['exception' => $e]);
603+
604+
$preview = $this->previewMapper->getPreviewForSpecification([
605+
'file_id' => $previewEntry->getFileId(),
606+
'width' => $previewEntry->getWidth(),
607+
'height' => $previewEntry->getHeight(),
608+
'mimetype_id' => $previewEntry->getMimetypeId(),
609+
'cropped' => $previewEntry->isCropped(),
610+
'version_id' => $previewEntry->getVersion() ?? '-1',
611+
]);
612+
613+
if ($preview === null) {
614+
throw new \RuntimeException('Unable to save a preview because it already exists but fetching it again yield nothing');
615+
}
616+
return $preview;
617+
}
594618
}
595619
}

0 commit comments

Comments
 (0)