Skip to content

Commit f4879a7

Browse files
committed
fix: get all available previews on Oracle
Split the DB requests in chunk of 1000 for oracle compatibility. Signed-off-by: Carl Schwan <[email protected]>
1 parent 9adf6cc commit f4879a7

File tree

2 files changed

+50
-27
lines changed

2 files changed

+50
-27
lines changed

lib/private/Preview/PreviewService.php

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use OC\Preview\Db\Preview;
1414
use OC\Preview\Db\PreviewMapper;
1515
use OC\Preview\Storage\StorageFactory;
16+
use OCP\DB\QueryBuilder\IQueryBuilder;
1617
use OCP\IDBConnection;
1718

1819
class PreviewService {
@@ -34,36 +35,52 @@ public function deletePreview(Preview $preview): void {
3435
* @return \Generator<array{storageId: int, fileIds: int[]}>
3536
*/
3637
public function getAvailableFileIds(): \Generator {
37-
$maxQb = $this->connection->getQueryBuilder();
38-
$maxQb->select($maxQb->func()->max('id'))
39-
->from($this->previewMapper->getTableName())
40-
->groupBy('file_id');
41-
42-
$qb = $this->connection->getQueryBuilder();
43-
$qb->select('file_id', 'storage_id')
44-
->from($this->previewMapper->getTableName())
45-
->where($qb->expr()->in('id', $qb->createFunction($maxQb->getSQL())));
46-
47-
$result = $qb->executeQuery();
48-
49-
$lastStorageId = -1;
50-
/** @var int[] $fileIds */
51-
$fileIds = [];
52-
53-
// Previews next to each others in the database are likely in the same storage, so group them
54-
while ($row = $result->fetch()) {
55-
if ($lastStorageId !== (int)$row['storage_id']) {
56-
if ($lastStorageId !== -1) {
57-
yield ['storageId' => $lastStorageId, 'fileIds' => $fileIds];
58-
$fileIds = [];
38+
$lastId = null;
39+
while (true) {
40+
$maxQb = $this->connection->getQueryBuilder();
41+
$maxQb->select($maxQb->func()->max('id'))
42+
->from($this->previewMapper->getTableName())
43+
->groupBy('file_id')
44+
->setMaxResults(IQueryBuilder::MAX_IN_PARAMS);
45+
46+
$qb = $this->connection->getQueryBuilder();
47+
48+
if ($lastId !== null) {
49+
$maxQb->andWhere($maxQb->expr()->gt('id', $qb->createNamedParameter($lastId)));
50+
}
51+
52+
$qb->select('id', 'file_id', 'storage_id')
53+
->from($this->previewMapper->getTableName())
54+
->where($qb->expr()->in('id', $qb->createFunction($maxQb->getSQL())));
55+
56+
$result = $qb->executeQuery();
57+
58+
$lastStorageId = -1;
59+
/** @var int[] $fileIds */
60+
$fileIds = [];
61+
62+
$found = false;
63+
// Previews next to each others in the database are likely in the same storage, so group them
64+
while ($row = $result->fetch()) {
65+
$found = true;
66+
if ($lastStorageId !== (int)$row['storage_id']) {
67+
if ($lastStorageId !== -1) {
68+
yield ['storageId' => $lastStorageId, 'fileIds' => $fileIds];
69+
$fileIds = [];
70+
}
71+
$lastStorageId = (int)$row['storage_id'];
5972
}
60-
$lastStorageId = (int)$row['storage_id'];
73+
$fileIds[] = (int)$row['file_id'];
74+
$lastId = $row['id'];
75+
}
76+
77+
if (count($fileIds) > 0) {
78+
yield ['storageId' => $lastStorageId, 'fileIds' => $fileIds];
6179
}
62-
$fileIds[] = (int)$row['file_id'];
63-
}
6480

65-
if (count($fileIds) > 0) {
66-
yield ['storageId' => $lastStorageId, 'fileIds' => $fileIds];
81+
if (!$found) {
82+
break;
83+
}
6784
}
6885
}
6986

lib/public/DB/QueryBuilder/IQueryBuilder.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ interface IQueryBuilder {
117117
*/
118118
public const MAX_ROW_DELETION = 100000;
119119

120+
/**
121+
* @since 33.0.0 Indicates how many params can be added in an IN condition
122+
* with an Oracle database server.
123+
*/
124+
public const MAX_IN_PARAMS = 1000;
125+
120126
/**
121127
* Enable/disable automatic prefixing of table names with the oc_ prefix
122128
*

0 commit comments

Comments
 (0)