Skip to content

Commit ed5c0e2

Browse files
committed
fix: get all available previews on Oracle
Split the DB requests in chunk of 1000 and use INNER JOIN instead of IN as this is better supported on all DB. Signed-off-by: Carl Schwan <[email protected]>
1 parent 9adf6cc commit ed5c0e2

File tree

4 files changed

+51
-32
lines changed

4 files changed

+51
-32
lines changed

lib/private/DB/QueryBuilder/Partitioned/PartitionSplit.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
namespace OC\DB\QueryBuilder\Partitioned;
1010

11+
use OCP\DB\QueryBuilder\IQueryFunction;
12+
1113
/**
1214
* Information about a database partition, containing the tables in the partition and any active alias
1315
*/
@@ -16,7 +18,7 @@ class PartitionSplit {
1618
public array $aliases = [];
1719

1820
/**
19-
* @param string[] $tables
21+
* @param (string|IQueryFunction)[] $tables
2022
*/
2123
public function __construct(
2224
public string $name,

lib/private/DB/QueryBuilder/Partitioned/PartitionedQueryBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ public function innerJoin($fromAlias, $join, $alias, $condition = null): self {
205205
}
206206

207207
public function leftJoin($fromAlias, $join, $alias, $condition = null): self {
208-
return $this->join($fromAlias, (string)$join, $alias, $condition, PartitionQuery::JOIN_MODE_LEFT);
208+
return $this->join($fromAlias, $join, $alias, $condition, PartitionQuery::JOIN_MODE_LEFT);
209209
}
210210

211211
public function join($fromAlias, $join, $alias, $condition = null, $joinMode = PartitionQuery::JOIN_MODE_INNER): self {

lib/private/Preview/PreviewService.php

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -34,36 +34,53 @@ public function deletePreview(Preview $preview): void {
3434
* @return \Generator<array{storageId: int, fileIds: int[]}>
3535
*/
3636
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 = [];
37+
$lastId = null;
38+
while (true) {
39+
$maxQb = $this->connection->getQueryBuilder();
40+
$maxQb->selectAlias($maxQb->func()->max('id'), 'max_id')
41+
->from($this->previewMapper->getTableName())
42+
->groupBy('file_id')
43+
->orderBy('max_id', 'ASC');
44+
45+
$qb = $this->connection->getQueryBuilder();
46+
47+
if ($lastId !== null) {
48+
$maxQb->andWhere($maxQb->expr()->gt('id', $qb->createNamedParameter($lastId)));
49+
}
50+
51+
$qb->select('id', 'file_id', 'storage_id')
52+
->from($this->previewMapper->getTableName(), 'p1')
53+
->innerJoin('p1', $qb->createFunction('(' . $maxQb->getSQL() . ')'), 'p2', $qb->expr()->eq('p1.id', 'p2.max_id'))
54+
->setMaxResults(1000);
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: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ public function from($from, $alias = null);
524524
* </code>
525525
*
526526
* @param string $fromAlias The alias that points to a from clause.
527-
* @param string $join The table name to join.
527+
* @param string|IQueryFunction $join The table name to join.
528528
* @param string $alias The alias of the join table.
529529
* @param string|ICompositeExpression|null $condition The condition for the join.
530530
*
@@ -549,7 +549,7 @@ public function join($fromAlias, $join, $alias, $condition = null);
549549
* </code>
550550
*
551551
* @param string $fromAlias The alias that points to a from clause.
552-
* @param string $join The table name to join.
552+
* @param string|IQueryFunction $join The table name to join.
553553
* @param string $alias The alias of the join table.
554554
* @param string|ICompositeExpression|null $condition The condition for the join.
555555
*
@@ -600,7 +600,7 @@ public function leftJoin($fromAlias, $join, $alias, $condition = null);
600600
* </code>
601601
*
602602
* @param string $fromAlias The alias that points to a from clause.
603-
* @param string $join The table name to join.
603+
* @param string|IQueryFunction $join The table name to join.
604604
* @param string $alias The alias of the join table.
605605
* @param string|ICompositeExpression|null $condition The condition for the join.
606606
*

0 commit comments

Comments
 (0)